Exemplo n.º 1
0
static int dot_contains(carmen_dot_filter_p f, double x, double y, double stdev) {

  double theta;
  double dx, dy, ux, uy, vx, vy, vxy;

  if (f->type == CARMEN_DOT_PERSON) {
    ux = f->person_filter.x;
    uy = f->person_filter.y;
    vx = f->person_filter.px;
    vy = f->person_filter.py;
    vxy = f->person_filter.pxy;
  }
  else if (f->type == CARMEN_DOT_TRASH) {
    ux = f->trash_filter.x;
    uy = f->trash_filter.y;
    vx = f->trash_filter.px;
    vy = f->trash_filter.py;
    vxy = f->trash_filter.pxy;
  }
  else {  // door
    ux = f->door_filter.x;
    uy = f->door_filter.y;
    vx = f->door_filter.px;
    vy = f->door_filter.py;
    vxy = f->door_filter.pxy;
  }

  dx = x - ux;
  dy = y - uy;

  theta = bnorm_theta(vx, vy, vxy);
  rotate2d(&dx, &dy, -theta);
  if (fabs(dx) <= stdev*sqrt(vx/fabs(cos(theta))) && 
      fabs(dy) <= stdev*sqrt(vy/fabs(sin(theta))))
    return 1;

  return 0;
}
wxThread::ExitCode  HaloRenderingThread::Entry()
{
    wxCommandEvent evt(wxEVT_HALO_RENDERING_THREAD_NOTIFY, wxID_ANY);

    setupStruct.resultValid = false;
    setupStruct.imageBuffer = 0;
    setupStruct.rayPaths = new map<RayPathId, RayPathDescriptor>;

    if (setupStruct.crystals.size() == 0)
    {
        evt.SetString(wxT("No crystal population set up."));
        evt.SetInt(1);
        setupStruct.notifee->AddPendingEvent(evt);
        return 0;
    }

    // Cast rays on crystals and refracted rays will form a pixel.

    int crystalTypeIndex = 0;
    CrystalDescriptor *currentDescriptor = &setupStruct.crystals[0];
    const int N_CRYSTAL_TYPES = setupStruct.crystals.size();
    int crystalsRemaining = currentDescriptor->populationWeight;
    Mesh currentMesh;
    size_t percentStep = setupStruct.crystalCount / 100;
    if (percentStep < 1) percentStep = 1;
    Vector3 sunPos(0, 0, -100000);
    rotate2d(sunPos.y, sunPos.z, setupStruct.solarAltitude * 3.14159265636 / 180.0);
    // Two prependicular vector
    Vector3 prepX = sunPos % Vector3(0, 1, 0); // FIXME: Sun on the zenith
    Vector3 prepY = sunPos % prepX;
    prepX /= ~prepX;
    prepY /= ~prepY;
    setupStruct.deleteBuffer = freeBuffer;
    setupStruct.deleteMap = freeMap;
    size_t size = setupStruct.imageSize;
    setupStruct.imageBuffer = new uint32_t[size * size * 6];
    memset(setupStruct.imageBuffer, 0, size * size * 6 * sizeof(uint32_t));
    uint32_t *leftPlane = setupStruct.imageBuffer; // 0th plane
    uint32_t *rightPlane = setupStruct.imageBuffer + size * size; // 1st plane
    uint32_t *topPlane = setupStruct.imageBuffer + 2 * size * size; // 2nd plane
    uint32_t *bottomPlane = setupStruct.imageBuffer + 3 * size * size; // 3rd plane
    uint32_t *backPlane = setupStruct.imageBuffer + 4 * size * size; // 4th plane
    uint32_t *frontPlane = setupStruct.imageBuffer + 5 * size * size; // 5th plane
    double halfImageSize = size * 0.5;
    int maxRays = (setupStruct.maxRayCastInfoSize * 1000000) / (sizeof(RayPathDescriptor) + sizeof(RayPathId));
    if (maxRays == 0) maxRays = 1;
    int recordRayModulus = setupStruct.crystalCount / maxRays;
    if (!recordRayModulus) recordRayModulus = 1;

    struct RefractionColor
    {
        int rgb;
        double refractionIndex;
    };

    RefractionColor colors[] =
    {
        { 0x0000FF, 1.3072 },
        { 0x0080FF, 1.3094 },
        { 0x00FFFF, 1.31 },
        { 0x00FF80, 1.3107 },
        { 0x00FF00, 1.3114 },
        { 0x80FF00, 1.3125 },
        { 0xFFFF00, 1.3136 },
        { 0xFF8000, 1.3147 },
        { 0xFF0000, 1.3158 },
        { 0xFF0040, 1.3172 },
        { 0xFF0080, 1.32 },
    };

    const int N_COLORS = sizeof(colors) / sizeof(colors[0]);

    // Cast many rays.
    for (size_t i = 0; i < setupStruct.crystalCount; i++)
    {
        if (setupStruct.cancelled)
        {
            // If the user shut the rendering down...
            delete[] setupStruct.imageBuffer;
            setupStruct.imageBuffer = 0;
            return 0;
        }
        if (!crystalsRemaining)
        {
            // We iterate through the crystals based on their population weights.
            crystalTypeIndex++;
            if (crystalTypeIndex >= N_CRYSTAL_TYPES) crystalTypeIndex = 0;
            currentDescriptor = &setupStruct.crystals[crystalTypeIndex];
            crystalsRemaining = currentDescriptor->populationWeight;
        }
        // Get the raw mesh
        currentMesh = currentDescriptor->mesh;
        // Rotate it according to the orientation.
        Matrix orientationMatrix = getOrientationMatrix(currentDescriptor->orientation);
        // Apply wobbliness
        Vector3 wobbleRotationAxis(1, 0, 0);
        rotate2d(wobbleRotationAxis.x, wobbleRotationAxis.z, randFloat(0, 3.1415));
        double wobblinessLimit = currentDescriptor->wobbliness * 3.1415 / 180.0;
        Matrix wobbleMatrix = createRotationMatrix(
            wobbleRotationAxis,
            randFloatNormal(
                0,
                wobblinessLimit
            )
        );
        Matrix transformation = orientationMatrix % wobbleMatrix;
        transformMesh(currentMesh, transformation);

        // Crystal created, now cast a ray on it.
        Vector3 offset = prepX * randFloat(-1, 1) + prepY * randFloat(-1, 1);
        vector<RayPath> rayPaths;
        // Compute color here
        double colorCode = randFloat(0, N_COLORS - 1);
        RefractionColor prev = colors[(int)(floor(colorCode))];
        RefractionColor next = colors[(int)(ceil(colorCode))];
        double kColor = colorCode - floor(colorCode);
        RefractionColor currentColor;
        currentColor.rgb = prev.rgb;
        currentColor.refractionIndex = (1 - kColor) * prev.refractionIndex + kColor * next.refractionIndex;
        // Compute real poisition of the ray (Sun is a disk)
        Vector3 realSunPos = sunPos;
        Vector3 rayRotVector;
        double rayRotVectorLength;
        do
        {
            rayRotVector = realSunPos % getRandomVector();
            rayRotVectorLength = ~rayRotVector;
        }
        while (rayRotVectorLength == 0);
        rayRotVector /= rayRotVectorLength;
        realSunPos = transformVector(
            createRotationMatrix(
                rayRotVector,
                randFloat(
                    0,
                    setupStruct.solarDiskRadius * 3.1415926536 / 180.0
                )
            ),
            realSunPos
        );
        computeRayPathInGlassMesh(currentMesh, currentColor.refractionIndex, realSunPos + offset, -realSunPos, 0.01, rayPaths);
        /* Project rays on the six planes. */
        for (size_t j = 0; j < rayPaths.size(); j++)
        {
            RayPath &current = rayPaths[j];
            size_t pathLength = current.size();

            Vector3 exitDir = current[pathLength - 1].first - current[pathLength - 2].first;
            Vector3 projectionDir = -exitDir;

            double xPos, yPos;
            // select the plane to project on.
            uint32_t *plane;
            double xm = 1, ym = 1;
            int planeId;
            if ((fabs(projectionDir.x) > fabs(projectionDir.y)) && (fabs(projectionDir.x) > fabs(projectionDir.z)))
            {
                if (projectionDir.x < 0)
                {
                    plane = leftPlane;
                    planeId = 0;
                    xm = -1;
                }
                else
                {
                    plane = rightPlane;
                    planeId = 1;
                }
                xPos = xm * projectionDir.z / fabs(projectionDir.x) * halfImageSize + halfImageSize;
                yPos = -ym * projectionDir.y / fabs(projectionDir.x) * halfImageSize + halfImageSize;
            }
            if ((fabs(projectionDir.y) > fabs(projectionDir.x)) && (fabs(projectionDir.y) > fabs(projectionDir.z)))
            {
                if (projectionDir.y < 0)
                {
                    plane = bottomPlane;
                    planeId = 3;
                    ym = -1;
                }
                else
                {
                    plane = topPlane;
                    planeId = 2;
                }
                xPos = xm * projectionDir.x / fabs(projectionDir.y) * halfImageSize + halfImageSize;
                yPos = -ym * projectionDir.z / fabs(projectionDir.y) * halfImageSize + halfImageSize;
            }
            if ((fabs(projectionDir.z) > fabs(projectionDir.x)) && (fabs(projectionDir.z) > fabs(projectionDir.y)))
            {
                if (projectionDir.z < 0)
                {
                    plane = frontPlane;
                    planeId = 5;
                }
                else
                {
                    plane = backPlane;
                    planeId = 4;
                    xm = -1;
                }
                xPos = xm * projectionDir.x / fabs(projectionDir.z) * halfImageSize + halfImageSize;
                yPos = -ym * projectionDir.y / fabs(projectionDir.z) * halfImageSize + halfImageSize;
            }
            // Calculate the new intensity of the pixel.
            xPos = clampInInt(xPos, 0, size - 1);
            yPos = clampInInt(yPos, 0, size - 1);
            int prevPixel = plane[(int)(yPos) * size + (int)(xPos)];
            int nextPixel = 0;
            double intensity = current[pathLength - 2].second * 20;
            for (int j = 0; j < 3; j++)
            {
                int currentSaturation = (prevPixel >> (8 * j)) & 0xFF;
                int toAdd = (int)(((currentColor.rgb >> (8 * j)) & 0xFF) * intensity) >> 8;
                int nextSaturation;
                if (currentSaturation + toAdd > 255) nextSaturation = 255;
                else nextSaturation = currentSaturation + toAdd;
                nextPixel += (1 << (8 * j)) * nextSaturation * setupStruct.pixelIntensity;
            }
            plane[(int)(yPos) * size + (int)(xPos)] = nextPixel;
            // Record the ray if needed
            if (!(i % recordRayModulus))
            {
                RayPathId pixelId(planeId, (int)xPos, (int)yPos);
                RayPathDescriptor theDescriptor(
                    &currentDescriptor->mesh,
                    transformation,
                    realSunPos + offset,
                    -realSunPos,
                    intensity
                );
                map<RayPathId, RayPathDescriptor>::iterator it = setupStruct.rayPaths->find(pixelId);
                if (it == setupStruct.rayPaths->end())
                {
                    // If not found, insert it as new
                    setupStruct.rayPaths->insert(
                        make_pair(
                            pixelId,
                            theDescriptor
                        )
                    );
                }
                else if (it->second.intensity < intensity)
                {
                    // If found, update it if the current ray is more intense
                    it->second = theDescriptor;
                }
            }
        }

        if (i % percentStep == 0)
        {
            sendNotifyString(wxString::Format(wxT("Casting rays: %d%%"), i / percentStep));
        }

        crystalsRemaining--;
    }


    evt.SetString(wxT("Completed."));
    evt.SetInt(1); //< 1 means the operation is finished.
    setupStruct.resultValid = true;
    setupStruct.notifee->AddPendingEvent(evt);
    return 0;
}
Exemplo n.º 3
0
static int dot_filter(double x, double y) {

  int i, imax;
  double pmax, p;
  double ux, uy, dx, dy;
  double vx, vy, vxy;
  double theta;

  imax = -1;
  pmax = 0.0;

  if (map_prob(x, y) >= map_occupied_threshold)
    return 1;

  for (i = 0; i < num_filters; i++) {

    ux = filters[i].person_filter.x;
    uy = filters[i].person_filter.y;
    vx = filters[i].person_filter.px;
    vy = filters[i].person_filter.py;
    vxy = filters[i].person_filter.pxy;
    dx = x - ux;
    dy = y - uy;

    // check if (x,y) is roughly within 3 stdev's of (E[x],E[y])
    theta = bnorm_theta(vx, vy, vxy);
    rotate2d(&dx, &dy, -theta);
    if (fabs(dx) < 4.0*sqrt(vx/fabs(cos(theta))) && 
	fabs(dy) < 4.0*sqrt(vy/fabs(sin(theta)))) {
      p = bnorm_f(x, y, ux, uy, vx, vy, vxy);
      if (p > pmax) {
	pmax = p;
	imax = i;
      }
    }

    //printf("3 person std dev's = (%.2f, %.2f)\n",
    //   3.0*sqrt(vx/fabs(cos(theta))), 3.0*sqrt(vx/fabs(cos(theta))));

    ux = filters[i].trash_filter.x;
    uy = filters[i].trash_filter.y;
    vx = filters[i].trash_filter.px;
    vy = filters[i].trash_filter.py;
    vxy = filters[i].trash_filter.pxy;
    dx = x - ux;
    dy = y - uy;

    // check if (x,y) is roughly within 3 stdev's of (E[x],E[y])
    theta = bnorm_theta(vx, vy, vxy);
    rotate2d(&dx, &dy, -theta);
    if (fabs(dx) < 4.0*sqrt(vx/fabs(cos(theta))) && 
	fabs(dy) < 4.0*sqrt(vy/fabs(sin(theta)))) {
      p = bnorm_f(x, y, ux, uy, vx, vy, vxy);
      if (p > pmax) {
	pmax = p;
	imax = i;
      }
    }
    
    //printf("3 trash std dev's = (%.2f, %.2f)\n",
    //   3.0*sqrt(vx/fabs(cos(theta))), 3.0*sqrt(vx/fabs(cos(theta))));

    ux = filters[i].door_filter.x;
    uy = filters[i].door_filter.y;
    vx = filters[i].door_filter.px;
    vy = filters[i].door_filter.py;
    vxy = filters[i].door_filter.pxy;
    dx = x - ux;
    dy = y - uy;

    // check if (x,y) is roughly within 3 stdev's of (E[x],E[y])
    theta = bnorm_theta(vx, vy, vxy);
    rotate2d(&dx, &dy, -theta);
    if (fabs(dx) < 4.0*sqrt(vx/fabs(cos(theta))) && 
	fabs(dy) < 4.0*sqrt(vy/fabs(sin(theta)))) {
      p = bnorm_f(x, y, ux, uy, vx, vy, vxy);
      if (p > pmax) {
	pmax = p;
	imax = i;
      }
    }
    //printf("3 door std dev's = (%.2f, %.2f)\n",
    //   3.0*sqrt(vx/fabs(cos(theta))), 3.0*sqrt(vx/fabs(cos(theta))));
  }

  /*
  if (imax >= 0)
    printf("pmax = %.4f, map_prob = %.4f at filter %d (x=%.2f, y = %.2f)\n",
	   pmax, map_prob(x, y), imax, x, y);
  */

  if (imax >= 0 && pmax > map_prob(x, y)) {
    //printf("pmax = %.4f, map_prob = %.4f at filter %d (x=%.2f, y = %.2f)\n",
    //   pmax, map_prob(x, y), imax, x, y);
    filters[imax].person_filter.hidden_cnt = 0;
    person_filter_sensor_update(&filters[imax].person_filter, x, y);
    if (filters[imax].do_motion_update) {
      filters[imax].do_motion_update = 0;
      trash_filter_motion_update(&filters[imax].trash_filter);
      door_filter_motion_update(&filters[imax].door_filter);
      //filters[imax].updated = 1;
    }
    if (do_sensor_update || filters[imax].sensor_update_cnt < sensor_update_cnt) {
      filters[imax].sensor_update_cnt++;
      trash_filter_sensor_update(&filters[imax].trash_filter, x, y);
      door_filter_sensor_update(&filters[imax].door_filter, x, y);
      //filters[imax].updated = 1;
    }
    filters[imax].type = dot_classify(&filters[imax]);

    //if (filters[imax].type == CARMEN_DOT_PERSON)
    filters[imax].updated = 1;
    
    return 1;
  }

  return 0;
}
void HexagonalPrismGeneratorDialog::OngeneratePrismClick(wxCommandEvent& event)
{
    const double SIN60 = 0.866025404;

    double basicPoints[6][2] =
    {
        {1, 0},
        {0.5, SIN60},
        {-0.5, SIN60},
        {-1, 0},
        {-0.5, -SIN60},
        {0.5, -SIN60}
    }; //< Points of a hexagon.
    double prismHeight;
    prismHeightTextCtrl->GetValue().ToDouble(&prismHeight);
    vector<int> face;

    if (kernPrismRadioButton->GetValue())
    {
        // Create Kern basic points.
        // Kern prism's basal face is triangular.
        double sideFaceRatio;
        sideFaceRatioTextBox->GetValue().ToDouble(&sideFaceRatio);
        const double ANG120 = 3.1415926526 * 2.0/3.0;
        double angle1 = ANG120 * (sideFaceRatio) / (1 + sideFaceRatio);
        for (int i = 0; i < 3; i++)
        {
            double x = 1;
            double y = 0;
            rotate2d(x, y, i * ANG120);
            basicPoints[2 * i][0] = x;
            basicPoints[2 * i][1] = y;
            x = 1;
            y = 0;
            rotate2d(x, y, i * ANG120 + angle1);
            basicPoints[2 * i + 1][0] = x;
            basicPoints[2 * i + 1][1] = y;
        }
    }
    else if (parryPlateRadioButton->GetValue())
    {
        // generate oblate prism.
        double height;
        parryPlateHeightTextBox->GetValue().ToDouble(&height);
        for (int i = 0; i < 6; i++)
        {
            double tmpx = basicPoints[i][0];
            double tmpy = basicPoints[i][1];


            if (tmpx < 0)
            {
                basicPoints[i][0] = tmpx * height + (1 - height)*-1;
                basicPoints[i][1] = tmpy * height;
            }
            else
            {
                basicPoints[i][0] = tmpx * height + (1 - height);
                basicPoints[i][1] = tmpy * height;
            }
        }
    }

    initMesh(mesh);
    // Set vertices
    // First 6 vertex is for the front hexagonal face.
    for (int i = 0; i < 6; i++)
    {
        mesh.vertices.push_back(Vector3(basicPoints[i][0], basicPoints[i][1], prismHeight));
    }
    // Next 6 vertex is for the back hexagonal face
    for (int i = 0; i < 6; i++)
    {
        mesh.vertices.push_back(Vector3(basicPoints[i][0], basicPoints[i][1], -prismHeight));
    }
    // Make front face
    face.clear();
    for (int i = 0; i < 6; i++)
    {
        face.push_back(i);
    }
    mesh.faces.push_back(face);
    // Make back face
    face.clear();
    for (int i = 0; i < 6; i++)
    {
        face.push_back(i + 6);
    }
    mesh.faces.push_back(face);
    // Make side faces
    for (int i = 0; i < 6; i++)
    {
        int j = i + 1 == 6 ? 0 : i + 1;
        face.clear();
        // Add vertices on the front face
        face.push_back(i);
        face.push_back(j);
        // Add vertices on the back face
        face.push_back(j + 6);
        face.push_back(i + 6);

        mesh.faces.push_back(face);
    }
    // Scale the prism to fit in a sphere which has unit radius.
    double vertexDistance = ~mesh.vertices[0];  // All vertices are the same distance from the center.

    for (size_t i = 0; i < mesh.vertices.size(); i++)
    {
         mesh.vertices[i] /= vertexDistance;
    }


    EndModal(ID_BUTTON_GENERATEPRISM);
}