예제 #1
0
bool Obj::GroundCheck(IN OUT D3DXVECTOR3& groundPos) const
{
	bool find = false;
	D3DXVECTOR3 rayStart(groundPos.x, 1000.0f, groundPos.z);
	D3DXVECTOR3 rayDirection(0, -1, 0);
	for (size_t i = 0; i < objGround.size(); i += 3)
	{
		float u, v, distance;
		find = D3DXIntersectTri(
			&objGround[i],
			&objGround[i + 1],
			&objGround[i + 2],
			&rayStart,
			&rayDirection,
			&u, &v,
			&distance) != 0;
		if (find == true)
		{
			groundPos.y = 1000.0f - distance;
			//groundPos = objGround[i] + ( ( objGround[i + 1] - objGround[i] ) * u ) + ( ( objGround[i + 2] - objGround[i] ) * v );
			break;
		}
	}
	return find;
}
예제 #2
0
    virtual void renderScene(Scene* scene, RenderTarget* target, RayTracer* tracer)
    {
        RGBColor pixelColor;
        Ray ray;
        int recursionDepth = 0;
        Point2d samplePointUnit, samplePointPixel;

        float pixelSize = target->getPixelSize() / mZoom;
        ray.origin = mEyePosition;

        for(int r = 0; r < target->getHeight(); ++r)
        {
            for(int c = 0; c < target->getWidth(); ++c)
            {
                pixelColor = RGBColor();

                for(int numSample = 0; numSample < mSampler->getSampleNumber(); ++numSample)
                {
                    samplePointUnit = mSampler->getNextUnitSquareSample();
                    samplePointPixel.x = pixelSize * (c - 0.5 * target->getWidth() + samplePointUnit.x);
                    samplePointPixel.y = pixelSize * (r - 0.5 * target->getHeight() + samplePointUnit.y);
                    ray.direction = rayDirection(samplePointPixel);
                    pixelColor += tracer->traceRay(&ray, scene);
                }
                pixelColor /= mSampler->getSampleNumber();
                pixelColor *= mExposureTime;
                target->drawPixel(c, r, pixelColor);
            }
        }
    }
예제 #3
0
/* 
    * This is our ray / bolt collision routine for now.   
    * Basically, this is called on a ship unit to see if any ray or bolt given by some simple vectors collide with it
    *  We should probably first check against shields and then against the colTree to see if we hit the shields first
    *  Not sure yet if that would work though...  more importantly, we might have to modify end in here in order 
    *  to tell calling code that the bolt should stop at a given point. 
*/
Unit* Unit::rayCollide( const QVector &start, const QVector &end, Vector &norm, float &distance)
{
    Unit *tmp;
    float rad = this->rSize();
    if ( ( !SubUnits.empty() ) && graphicOptions.RecurseIntoSubUnitsOnCollision )
        if ( ( tmp = *SubUnits.fastIterator() ) )
            rad += tmp->rSize();
    if ( !globQuerySphere( start, end, cumulative_transformation_matrix.p, rad ) )
        return NULL;
    if (graphicOptions.RecurseIntoSubUnitsOnCollision) {
        if ( !SubUnits.empty() ) {
            un_fiter i( SubUnits.fastIterator() );
            for (Unit *un; (un = *i); ++i)
                if ( ( tmp = un->rayCollide( start, end, norm, distance) ) != 0 )
                    return tmp;
        }
    }
    QVector  st( InvTransform( cumulative_transformation_matrix, start ) );
    QVector  ed( InvTransform( cumulative_transformation_matrix, end ) );
    static bool sphere_test = XMLSupport::parse_bool( vs_config->getVariable( "physics", "sphere_collision", "true" ) );
    distance = querySphereNoRecurse( start, end );    
    if (distance > 0.0f || (this->colTrees&&this->colTrees->colTree( this, this->GetWarpVelocity() )&&!sphere_test)) {
        Vector coord;
        /* Set up points and ray to send to ray collider. */
        Opcode::Point rayOrigin(st.i,st.j,st.k);
        Opcode::Point rayDirection(ed.i,ed.j,ed.k);
        Opcode::Ray boltbeam(rayOrigin,rayDirection);
        if(this->colTrees){
            // Retrieve the correct scale'd collider from the unit's collide tree. 
            csOPCODECollider *tmpCol  = this->colTrees->colTree( this, this->GetWarpVelocity() );
            QVector del(end-start);
            //Normalize(del);
            norm = ((start+del*distance)-Position()).Cast();
            Normalize(norm);
            //RAY COLLIDE does not yet set normal, use that of the sphere center to current loc
            if (tmpCol==NULL) {
                
                return this;
            }
            if(tmpCol->rayCollide(boltbeam,norm,distance)){
                // compute real distance 
                distance = (end-start).Magnitude() * distance;
                
                // NOTE:   Here is where we need to retrieve the point on the ray that we collided with the mesh, and set it to end, create the normal and set distance
                VSFileSystem::vs_dprintf(3,"Beam collide with %p, distance %f\n",this,distance);
                return(this);
            }
        } else {//no col trees = a sphere
            // compute real distance
            distance = (end-start).Magnitude() * distance;
            
            VSFileSystem::vs_dprintf(3,"Beam collide with %p, distance %f\n",this,distance);
            return(this);
        }
    } else {
        return (NULL);
    }
    return(NULL);
}
예제 #4
0
bool HeightMap::OnTheGround(D3DXVECTOR3& pos, const D3DXVECTOR3& p0, const D3DXVECTOR3& p1, const D3DXVECTOR3& p2)
{
	bool find = false;

	D3DXVECTOR3 rayStart(pos.x, 1000.0f, pos.z);
	D3DXVECTOR3 rayDirection(0, -1, 0);

	float u, v, distance;
	find = D3DXIntersectTri(
		&p0, &p1, &p2,
		&rayStart, &rayDirection,
		&u, &v, &distance) != 0;

	if (find == true)
	{
		pos.y = 1000.0f - distance;

		//pos = p0 + (p1 - p0) * u + (p2 - p0) * v;
	}

	return find;
}
예제 #5
0
void Player::Raycast(const GameContext& gameContext)
{
	GameScene* scene = GetScene();

	XMFLOAT3 pos = GetTransform()->GetPosition();
	XMFLOAT3 fw = GetTransform()->GetForward();
	PxVec3 rayOrigin(pos.x,pos.y + 1.f,pos.z), rayDirection(fw.x,fw.y,fw.z);
	rayOrigin.x += fw.x * 2.5f;
	rayOrigin.z += fw.z * 2.5f;

	const PxU32 bufSize = 20;
	PxRaycastHit hit[bufSize];
	PxRaycastBuffer buf(hit, bufSize); // [out] Blocking and touching hits will be stored here

	if(scene->GetPhysxProxy()->Raycast(rayOrigin, rayDirection, 5000, buf))
	{
		for(PxU32 i = 0; i < buf.nbTouches; ++i)
		{
			BaseComponent* component = static_cast<BaseComponent*>(buf.touches[i].actor->userData);
			GameObject* go = component->GetGameObject();
			string name = go->GetName();	
			cout << "RAYCAST OBJECT: " << name << endl;		

			if(name == "Enemy")
			{
				Enemy* enemy = reinterpret_cast<Enemy*>(go);
				int dmg = 12.5f;
				enemy->Damage(dmg);
			}
		}

		PxVec3 vel = rayDirection * 1000;
		auto laser = new Laser(XMFLOAT3(vel.x, vel.y, vel.z));
		AddChild(laser);
	}
}
int FFDDistanceGridDiscreteIntersection::computeIntersection(Ray& e2, FFDDistanceGridCollisionElement& e1, OutputVector* contacts)
{
    Vector3 rayOrigin(e2.origin());
    Vector3 rayDirection(e2.direction());
    const double rayLength = e2.l();

    DistanceGrid* grid1 = e1.getGrid();
    FFDDistanceGridCollisionModel::DeformedCube& c1 = e1.getCollisionModel()->getDeformCube(e1.getIndex());

    // Center of the sphere
    const Vector3 center1 = c1.center;
    // Radius of the sphere
    const double radius1 = c1.radius;

    const Vector3 tmp = center1 - rayOrigin;
    double rayPos = tmp*rayDirection;
    const double dist2 = tmp.norm2() - (rayPos*rayPos);
    if (dist2 >= (radius1*radius1))
        return 0;

    double l0 = rayPos - sqrt(radius1*radius1 - dist2);
    double l1 = rayPos + sqrt(radius1*radius1 - dist2);
    if (l0 < 0) l0 = 0;
    if (l1 > rayLength) l1 = rayLength;
    if (l0 > l1) return 0; // outside of ray
    //const double dist = sqrt(dist2);
    //double epsilon = grid1->getCellWidth().norm()*0.1f;

    c1.updateFaces();
    DistanceGrid::Coord p1;
    const SReal cubesize = c1.invDP.norm();
    for(int i=0; i<100; i++)
    {
        rayPos = l0 + (l1-l0)*(i*0.01);
        p1 = rayOrigin + rayDirection*rayPos;
        // estimate the barycentric coordinates
        DistanceGrid::Coord b = c1.undeform0(p1);
        // refine the estimate until we are very close to the p2 or we are sure p2 cannot intersect with the object
        int iter;
        //SReal err1 = 1000.0f;
        bool found = false;
        for(iter=0; iter<5; ++iter)
        {
            DistanceGrid::Coord pdeform = c1.deform(b);
            DistanceGrid::Coord diff = p1-pdeform;
            SReal err = diff.norm();
            //if (iter>3)
            //    sout << "Iter"<<iter<<": "<<err1<<" -> "<<err<<" b = "<<b<<" diff = "<<diff<<" d = "<<grid1->interp(c1.initpos(b))<<""<<sendl;
            SReal berr = err*cubesize; if (berr>0.5f) berr=0.5f;
            if (b[0] < -berr || b[0] > 1+berr
                || b[1] < -berr || b[1] > 1+berr
                || b[2] < -berr || b[2] > 1+berr)
                break; // far from the cube
            if (err < 0.001f)
            {
                // we found the corresponding point, but is is only valid if inside the current cube
                if (b[0] > -0.1f && b[0] < 1.1f
                    && b[1] > -0.1f && b[1] < 1.1f
                    && b[2] > -0.1f && b[2] < 1.1f)
                {
                    found = true;
                }
                break;
            }
            //err1 = err;
            b += c1.undeformDir( b, diff );
        }
        if (found)
        {
            SReal d = grid1->interp(c1.initpos(b));
            if (d < 0)
            {
                // intersection found

                contacts->resize(contacts->size()+1);
                DetectionOutput *detection = &*(contacts->end()-1);

                detection->point[0] = e2.origin() + e2.direction()*rayPos;
                detection->point[1] = c1.initpos(b);
                detection->normal = e2.direction(); // normal in global space from p1's surface
                detection->value = d;
                detection->elem.first = e2;
                detection->elem.second = e1;
                detection->id = e2.getIndex();
                return 1;
            }
        }
        // else move along the ray
        //if (dot(Vector3(grid1->grad(c1.initpos(b))),rayDirection) < 0)
        //    rayPos += 0.5*d;
        //else
        //    rayPos -= 0.5*d;
    }
    return 0;
}
예제 #7
0
파일: Mesh.cpp 프로젝트: aaweb/GamePlay
void Mesh::generateHeightmap(const char* filename)
{
    // Shoot rays down from a point just above the max Y position of the mesh.
    // Compute ray-triangle intersection tests against the ray and this mesh to 
    // generate heightmap data.
    Vector3 rayOrigin(0, bounds.max.y + 10, 0);
    Vector3 rayDirection(0, -1, 0);
    Vector3 intersectionPoint;
    int minX = (int)ceil(bounds.min.x);
    int maxX = (int)floor(bounds.max.x);
    int minZ = (int)ceil(bounds.min.z);
    int maxZ = (int)floor(bounds.max.z);
    int width = maxX - minX + 1;
    int height = maxZ - minZ + 1;
    float* heights = new float[width * height];
    int index = 0;
    float minHeight = FLT_MAX;
    float maxHeight = FLT_MIN;
    for (int z = minZ; z <= maxZ; z++)
    {
        rayOrigin.z = (float)z;
        for (int x = minX; x <= maxX; x++)
        {
            float h;
            rayOrigin.x = (float)x;
            if (intersect(rayOrigin, rayDirection, vertices, parts, &intersectionPoint))
            {
                h = intersectionPoint.y;
            }
            else
            {
                h = 0;
                fprintf(stderr, "Warning: Heightmap triangle intersection failed for (%d, %d).\n", x, z);
            }
            if (h < minHeight)
                minHeight = h;
            if (h > maxHeight)
                maxHeight = h;
            heights[index++] = h;
        }
    }
    
    // Normalize the max height value
    maxHeight = maxHeight - minHeight;

    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    png_bytep row = NULL;

    FILE* fp = fopen(filename, "wb");
    if (fp == NULL)
    {
        fprintf(stderr, "Error: Failed to open file for writing: %s\n", filename);
        goto error;
    }

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL)
    {
        fprintf(stderr, "Error: Write struct creation failed: %s\n", filename);
        goto error;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL)
    {
        fprintf(stderr, "Error: Info struct creation failed: %s\n", filename);
        goto error;
    }

    png_init_io(png_ptr, fp);

    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

    png_write_info(png_ptr, info_ptr);

    // Allocate memory for a single row of image data
    row = (png_bytep)malloc(3 * width * sizeof(png_byte));

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            // Write height value normalized between 0-255 (between min and max height)
            float h = heights[y*width + x];
            float nh = (h - minHeight) / maxHeight;
            png_byte b = (png_byte)(nh * 255.0f);
            
            int pos = x*3;
            row[pos] = row[pos+1] = row[pos+2] = b;
        }
        png_write_row(png_ptr, row);
    }

    png_write_end(png_ptr, NULL);
    DEBUGPRINT_VARG("> Saved heightmap: %s\n", filename);

error:
    if (heights)
        delete[] heights;
    if (fp)
        fclose(fp);
    if (row)
        free(row);
    if (info_ptr)
        png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
    if (png_ptr)
        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);

}
예제 #8
0
Ray PinholeCamera::getRayTo(Vector2 location) {
    return Ray(origin, rayDirection(location));
}