Ejemplo n.º 1
0
bool GameMain::Raycast(float maxDistance, Vector3& hitPos, Vector3& hitNormal, Drawable*& hitDrawable)
{
	hitDrawable = 0;

	Graphics* graphics = GetSubsystem<Graphics>();
	//Ray cameraRay = camera->GetScreenRay((float)graphics->GetWidth() * 0.5f, (float) graphics->GetHeight() * 0.5f);
	Ray ray = world.camera.camera_->GetScreenRay((float) 0.5f, (float) 0.5f);
	//Ray gunRay = Ray(gunNode_->GetWorldPosition(), gunNode_->GetWorldDirection());

	// Pick only geometry objects, not eg. zones or lights, only get the first (closest) hit
	PODVector<RayQueryResult> results;
	//RayOctreeQuery query(results, cameraRay, RAY_TRIANGLE, maxDistance, DRAWABLE_GEOMETRY);
	RayOctreeQuery query(results, ray, RAY_TRIANGLE, maxDistance, DRAWABLE_GEOMETRY, 191);
		
	Octree* octree = scene_->GetComponent<Octree>();
	//octree->RaycastSingle(query);
	octree->Raycast(query);

	if (results.Size())
	{
		for (unsigned int i = 0; i < results.Size(); i++) 
		{
			RayQueryResult& result = results[i];

			Variant fx = result.node_->GetVar("fx");
			if (fx.GetInt() == 1) continue;

			hitPos = result.position_;
			hitNormal = result.normal_;
			hitDrawable = result.drawable_;

			return true;
		}			
	}

	return false;
}
static int Octree_Raycast(duk_context* ctx)
{
    bool single = duk_get_current_magic(ctx) == DUK_MAGIC_RAYCAST_SINGLE;

    duk_idx_t nargs = duk_get_top(ctx);

    // require at least the ray
    if (nargs < 1)
    {
        duk_push_undefined(ctx);
        return 1;
    }

    Ray ray;
    if (!duk_get_ray(ctx, 0, ray))
    {
        duk_push_undefined(ctx);
        return 1;
    }

    RayQueryLevel level = RAY_TRIANGLE;
    if (nargs > 1)
    {
        unsigned _level = (unsigned) duk_to_number(ctx, 1);
        if (_level > (unsigned) RAY_TRIANGLE_UV)
        {
            duk_push_undefined(ctx);
            return 1;
        }

        level = (RayQueryLevel) _level;
    }

    float maxDistance = M_INFINITY;
    if (nargs > 2)
    {
        maxDistance = (float) duk_to_number(ctx, 2);
    }

    unsigned char drawableFlags = DRAWABLE_ANY;
    if (nargs > 3)
    {
        drawableFlags = (unsigned char) duk_to_number(ctx, 3);
    }

    unsigned viewMask = DEFAULT_VIEWMASK;
    if (nargs > 4)
    {
        viewMask = (unsigned) duk_to_number(ctx, 4);
    }

    duk_push_this(ctx);
    Octree* octree = js_to_class_instance<Octree>(ctx, -1, 0);

    PODVector<RayQueryResult> result;
    RayOctreeQuery query(result, ray, level, maxDistance, drawableFlags, viewMask);

    single ? octree->RaycastSingle(query) : octree->Raycast(query);

    // handle case of nothing hit
    if (!result.Size())
    {
        if (single)
            duk_push_null(ctx);
        else
            duk_push_array(ctx);

        return 1;
    }
    else
    {
        if (single)
        {
            duk_push_rayqueryresult(ctx, result[0]);
        }
        else
        {
            duk_push_array(ctx);

            for (unsigned i = 0; i < result.Size(); i++)
            {
                duk_push_rayqueryresult(ctx, result[i]);
                duk_put_prop_index(ctx, -2, i);
            }
        }
    }

    return 1;
}