Esempio n. 1
0
 void Run(EntityManager& em, CSnakeGame& gsnake) {
     CGrid& grid = gsnake.GetGrid();
     for (auto a = em.begin(); a != em.end(); a++) {
         if (!(*a)->HasComponent<CMotion>() || !(*a)->HasComponent<CHead>()) {
             continue;
         }
         if (!IsInsideGrid(*(*a)->GetComponent<CMotion>(), gsnake.GetGrid().GetGridSize())) {
             gsnake.GameOver();
         }
     }
     for (auto a = em.begin(); a != em.end(); a++) {
         if ((*a).get() == 0 || !(*a)->HasComponent<CPlayerControlled>()) {
             continue;
         }
         CHead* head_a = (*a)->GetComponent<CHead>();
         CMotion* motion_a = (*a)->GetComponent<CMotion>();
         for (auto b = em.begin(); b != em.end(); b++) {
             if ((*b).get() == 0 || a == b || !(*b)->HasComponent<CMotion>()) {
                 continue;
             }
             CMotion* motion_b = (*b)->GetComponent<CMotion>();
             if (motion_a->GetCoords() == motion_b->GetCoords()) {
                 std::pair<int, int> xy = motion_b->GetCoords();
                 if (grid.Get(xy.first, xy.second) < 0) {
                     head_a->SetLength(head_a->GetLength() + 1);
                     xy = grid.EatFood(xy.first, xy.second);
                     em.MarkAdded(std::unique_ptr<CEntity>(new CFood(xy.first, xy.second)));
                     em.MarkRemoved(*b);
                 } else if (grid.Get(xy.first, xy.second) > 0 || (*b)->HasComponent<CHead>()) {
                     gsnake.GameOver();
                 }
             }
         }
     }
     em.Update();
 }
Esempio n. 2
0
bool VoxelGrid::Trace(const SceneObject* parentObject, Ray* inputRay, IntersectionState* outputIntersection)
{
    glm::mat4 spaceTransform(1.f);
    if (parentObject) {
        spaceTransform = parentObject->GetWorldToObjectMatrix();
    }
    glm::vec3 rayPos = glm::vec3(spaceTransform * inputRay->GetPosition());
    const glm::vec3 rayDir = glm::vec3(spaceTransform * inputRay->GetForwardDirection());
    glm::ivec3 step;
    for (int i = 0; i < 3; ++i) {
        if (std::abs(rayDir[i]) < SMALL_EPSILON) {
            step[i] = 0;
        } else {
            step[i] = (rayDir[i] > SMALL_EPSILON) ? 1 : -1;
        }
    }

    // Implementation of "A Fast Voxel Traversal Algorithm for Ray Tracing" by John Amanatides and Andrew Woo
    // Link: http://www.cse.chalmers.se/edu/year/2010/course/TDA361/grid.pdf
    glm::ivec3 currentVoxelIndex = GetVoxelForPosition(rayPos, false);
#if DEBUG_VOXEL_GRID
    std::cout << "Initial Voxel Position: " << glm::to_string(currentVoxelIndex) << " for " << glm::to_string(rayPos) << " going " << glm::to_string(rayDir) << std::endl;
#endif
    // If we aren't currently within the grid, move the ray position such that we are.
    if (!IsInsideGrid(currentVoxelIndex)) {
        IntersectionState tempState;
        if (!boundingBox.Trace(parentObject, inputRay, &tempState)) {
            return false;
        }
        const float dt = tempState.intersectionT + SMALL_EPSILON;
        currentVoxelIndex = GetVoxelForPosition(rayPos + rayDir * dt);
    }
       
#if DEBUG_VOXEL_GRID
    std::cout << "Final Voxel Position: " << glm::to_string(currentVoxelIndex) << " for " << glm::to_string(rayPos) << " going " << glm::to_string(rayDir) << std::endl;
    std::cout << "Scene Bounding: " << glm::to_string(boundingBox.minVertex) << " " << glm::to_string(boundingBox.maxVertex) << std::endl;
    std::cout << "Voxel Size: " << glm::to_string(voxelSize) << std::endl;
#endif
    while (IsInsideGrid(currentVoxelIndex)) {
#if DEBUG_VOXEL_GRID
        std::cout << "Trace Voxel: " << glm::to_string(currentVoxelIndex) << std::endl;
#endif
        IntersectionState tempIntersection;
        tempIntersection.TestAndCopyLimits(outputIntersection);
        bool hitVoxel = grid[currentVoxelIndex[0]][currentVoxelIndex[1]][currentVoxelIndex[2]].Trace(parentObject, inputRay, &tempIntersection);
            
        // Need to verify that the hit position is within the voxel -- otherwise we're looking too far ahead.
        const glm::vec3 hitPosition = rayPos + rayDir * tempIntersection.intersectionT;
#if DEBUG_VOXEL_GRID
        std::cout << "  -- hit position " << glm::to_string(hitPosition) << " " << glm::to_string(GetVoxelForPosition(hitPosition)) << std::endl;
#endif
        if (hitVoxel && GetVoxelForPosition(hitPosition) == currentVoxelIndex)  {
            if (outputIntersection) {
                *outputIntersection = tempIntersection;
            }
#if DEBUG_VOXEL_GRID
            std::cout << " did done hit" << std::endl;
#endif
            return true;
        }

        int minIndex = 0;
        float minTMax = 0.f;
        FindClosestVoxelSide(minIndex, minTMax, currentVoxelIndex, step, rayPos, rayDir);
        assert(minIndex >= 0);
        currentVoxelIndex[minIndex] += step[minIndex];

#if DEBUG_VOXEL_GRID
        std::cout << " -- next voxel: " << glm::to_string(currentVoxelIndex) << " " << minIndex << " " << minTMax << std::endl;
#endif
    }
    return false;
}