摄像机速度取决于3D场景范围

时间:2014-06-03 08:41:23

标签: performance 3d camera

我正在使用HOOPS Engine

处理3D场景查看器

我想实现对3D鼠标的支持。一切都很好,但还有一个问题,我不知道如何解决:

我用以下公式移动相机:

HC_Dolly_Camera(-(factor.x * this->m_speed), factor.y * this->m_speed, factor.z * this->m_speed);

this-> m_speed取决于场景范围。但如果场景非常大(例如机场),那么摄像机的速度很快就会变得很快。

我的第一次尝试是实现一种阻尼因子,这取决于从物体到相机的距离。它工作......不知何故。有时我注意到了丑陋的“弹跳效果”,我可以通过平滑加速和改进的余弦函数来避免这种效果。

但我的问题是:在3D场景的特殊情况下,是否有降低相机速度的最佳做法?我的方法很有效,但我认为这不是一个好的解决方案,因为它使用了许多光线投射。

祝你好运, peekaboo777

P.S:

我的代码

if(!this->smooth_damping)
{
    if(int res = HC_Compute_Selection_By_Area(this->view->GetDriverPath(), ".", "v", -0.5, 0.5, -0.5, 0.5) > 0)
    {
        float window_x, window_y, window_z, camera_x, camera_y, camera_z;

        double dist_length = 0;
        double shortest_dist = this->max_world_extent;

        while(HC_Find_Related_Selection()) 
        {
            HC_Show_Selection_Position(&window_x, &window_y, &window_z, &camera_x, &camera_y, &camera_z);
            this->view->GetCamera(&this->cam);

            // Compute distance vector
            this->dist.Set(cam.position.x - camera_x, cam.position.y - camera_y, cam.position.z - camera_z);
            dist_length = sqrt(pow((cam.position.x - camera_x), 2) + pow((cam.position.y - camera_y), 2) + pow((cam.position.z - camera_z), 2));

            if(dist_length < shortest_dist)
                shortest_dist = dist_length;
        }
        // Reduced computation

        // Compute damping factor
        damping_factor = ((1 - 8) / (this->max_world_extent - 1)) * (shortest_dist - 1) + 8;

        // Difference to big? (Gap)
        if(qFabs(damping_factor - damping_factor * 0.7) < qFabs(damping_factor - this->last_damping_factor))
        {
            this->smooth_damping = true;
            this->damping_factor_to_reach = damping_factor; // this is the new damping factor we have to reach
            this->freezed_damping_factor = this->last_damping_factor; // damping factor before gap.

            if(this->last_damping_factor > damping_factor) // Negative acceleration
            {
                this->acceleration = false;
            }
            else // Acceleration
            {
                this->acceleration = true;
            }
        }
        else
        {
            this->last_damping_factor = damping_factor;
        }
    }
}
else
{
    if(this->acceleration)
    {
        if(this->freezed_damping_factor -= 0.2 >= 1);

        damping_factor = this->freezed_damping_factor + 
                         (((this->damping_factor_to_reach - this->freezed_damping_factor) / 2) - 
                         ((this->damping_factor_to_reach - this->freezed_damping_factor) / 2) * 
                         qCos(M_PI * this->damping_step)); // cosine function between freezed and to reach

        this->last_damping_factor = damping_factor;

        if(damping_factor >= this->damping_factor_to_reach)
        {
            this->smooth_damping = false;
            this->damping_step = 0;
            this->freezed_damping_factor = 0;
        } // Reset
    }
    else
    {
        if(this->freezed_damping_factor += 0.2 >= 1);

        damping_factor = this->damping_factor_to_reach + 
                         ((this->freezed_damping_factor - this->damping_factor_to_reach) - 
                         (((this->freezed_damping_factor - this->damping_factor_to_reach) / 2) - 
                         ((this->freezed_damping_factor - this->damping_factor_to_reach) / 2) * 
                         qCos(M_PI * this->damping_step))); // cosine functio between to reach and freezed

        this->last_damping_factor = damping_factor;

        if(damping_factor <= this->damping_factor_to_reach)
        {
            this->smooth_damping = false;
            this->damping_step = 0;
            this->freezed_damping_factor = 0;
        } // Reset
    }

    this->damping_step += 0.01; // Increase the "X"
}

2 个答案:

答案 0 :(得分:0)

我从未使用过HOOPS引擎,但你有没有办法让最近的物体到相机?您可以使用此值缩放速度,因此相机会在靠近对象时变慢。

更好的方法是在边界框上取最近点而不是对象中心。这样可以改善靠近长物体/地板等大物体的行为。

我尝试的另一种解决方案是通过视图中心进行光线投射以寻找第一个对象并以相同的方式使用距离。在这种方法中,你不会被你身后的物体放慢速度。您还可以添加额外的光线投射点,例如1/4的屏幕并混合结果值,这样您就可以获得更加恒定的速度刻度。

我从你的问题中理解的是,你想要一种方法来引导相机通过大型场景,比如机场,并且仍然可以慢慢靠近物体移动。我不认为有一种“普遍”的做法。所有这些都取决于您的引擎/ API功能和特定需求。如果所有这些解决方案都不起作用,也许你应该尝试使用纸和笔;)。

答案 1 :(得分:0)

你说m_speed依赖于场景范围,我猜这种依赖是线性的(线性意味着如果你用sExtent测量场景扩展,m_speed等于c * sExtent,c是一些常数系数)。 / p>

因此,为了使m_speed依赖于场景范围,但为大规模场景避免巨大的m_speed,我建议将m_speed的依赖性设置为sExtent非线性,如对数依赖:

m_speed = c*log(sExtent+1) 

这样,如果场景较大,你的m_speed会更大,但不会以相同的比例。你也可以使用激进来创建非线性依赖。您可以在下面比较这些功能:

enter image description here