小编Tom*_*Tom的帖子

两个四元数之间的差异

解决了


我正在我的引擎中制作一个3D门户系统(比如Portal游戏).每个门户都有自己的方向保存在四元数中.要在其中一个门户中渲染虚拟场景,我需要计算两个四元数之间的差异,结果用于旋转虚拟场景.

当在左墙上创建第一个门户,在右墙上创建第二个门户时,从一个到另一个的旋转将仅在一个轴上进行,但是例如当第一个门户将在地板上创建时,第二个门户将在地板上创建在右侧墙上,从一个轴到另一个轴的旋转可能在两个轴上,这就是问题,因为旋转出错了.

我认为问题的存在是因为例如X轴和Z轴的方向一起存储在一个四元数中,我需要它单独地进行手工乘法X*Z(或Z*X),但是如何只使用一个四元数(差值四元数)?或者还有其他方法来纠正旋转场景吗?

编辑:

这张照片上有两个门户P1和P2,箭头显示它们是如何旋转的.在我看P1时,我会看到P2的内容.要找到我需要旋转主场景的旋转,就像这张图片中的虚拟场景,我正在做以下事情:

  1. 从四元数P2到四元数P1的区别
  2. 在Y轴上旋转180度(门户网站向上)
  3. 使用结果旋转虚拟场景

上述方法仅在差异仅在一个轴上发生时才有效.当一个门户在地板上或在天花板上时,这将不起作用,因为差异四元数是在多个轴上构建的.正如所建议的那样,我试图将P1的四元数乘以P2的四元数,反过来但这不起作用.

在此输入图像描述

编辑2:

要找到从P2到P1的差异,我正在做以下事情:

Quat q1 = P1->getOrientation();
Quat q2 = P2->getOrientation();

Quat diff = Quat::diff(q2, q1);  // q2 * diff = q1 //
Run Code Online (Sandbox Code Playgroud)

这是Quat :: diff函数:

GE::Quat GE::Quat::diff(const Quat &a, const Quat &b)
{
    Quat inv = a;
    inv.inverse();
    return inv * b;
}
Run Code Online (Sandbox Code Playgroud)

逆:

void GE::Quat::inverse()
{
    Quat q = (*this);
    q.conjugate();
    (*this) = q / Quat::dot((*this), (*this)); …
Run Code Online (Sandbox Code Playgroud)

math portal-system rotation quaternions

13
推荐指数
2
解决办法
4万
查看次数

如何找到从一个向量到另一个向量的正确旋转?

我有两个对象,每个对象有两个向量:

  • 法线向量
  • 向上矢量

就像这张图片:

在此处输入图片说明

向上向量垂直于法向量。现在我想找到从一个对象到另一个对象的唯一旋转,该怎么做?

我有一种方法可以找到一个向量到另一个向量之间的旋转,并且它有效。问题是我需要注意两个向量:法向量和向上向量。如果我使用此方法将法线向量从对象 1 旋转到对象 2 的法线,则向上向量可能指向错误的方向,并且它们需要平行。

这是查找最短旋转的代码:

GE::Quat GE::Quat::fromTo(const Vector3 &v1, const Vector3 &v2)
{
    Vector3 a = Vector3::cross(v1, v2);
    Quat q;

    float dot = Vector3::dot(v1, v2);

    if ( dot >= 1 ) 
    {
        q = Quat(0,0,0,1);

    }
    else if ( dot < -0.999999 )
    {
        Vector3 axis = Vector3::cross(Vector3(1,0,0),v2);

        if (axis.length() == 0) // pick another if colinear
                axis = Vector3::cross(Vector3(0,1,0),v2);
        axis.normalize();
        q = Quat::axisToQuat(axis,180);
    }
    else
    {
        float s = sqrt( (1+dot)*2 );
        float …
Run Code Online (Sandbox Code Playgroud)

c++ opengl rotation quaternions

6
推荐指数
1
解决办法
1万
查看次数

C++ 11智能指针总是代替new/delete?

在C++ 11中我们应该总是使用unique_ptrshared_ptr代替new/ delete?性能如何,智能指针要慢得多?

c++ performance smart-pointers new-operator c++11

5
推荐指数
1
解决办法
1883
查看次数

AdMob 广告未在 Android SDL 应用中正确显示

我在我的应用中实施 AdMob 广告时遇到了问题。我正在使用SDL和本机代码。广告是在这样的onCreate方法中创建的:

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    Log.v("SDL", "onCreate():" + mSingleton);
    super.onCreate(savedInstanceState);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    SDLActivity.initialize();
    mSingleton = this;

    mSurface = new SDLSurface(getApplication());
    mLayout = new RelativeLayout(this);

    adView = new AdView( this );
    adView.setAdUnitId("ca-app-pub-XXXXXXXXXXXXXXXX/XXXXXXXXXX");
    adView.setAdSize(AdSize.BANNER);

    request = new AdRequest.Builder()
    .addTestDevice("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
    .build();

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    adView.loadAd(request);

    mLayout.addView(mSurface);
    mLayout.addView(adView, params);

    setContentView(mLayout);

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
Run Code Online (Sandbox Code Playgroud)

我认为这段代码是正确的,因为广告位于屏幕上,但不可见。我可以触摸屏幕上应显示广告的位置,然后浏览器开始打开,因此广告实际上已加载。

在以下情况下,广告将正确显示:

  • 是时候刷新了(在 AdMob 帐户上设置,我设置了 30 秒)
  • 我退出应用程序然后继续,当从类中调用onPauseonResume方法时Activity

我正在考虑一些刷新方法,但找不到解决此问题的方法。我试过的这个方法:

adView.refreshDrawableState();
adView.setActivated( true );
adView.setEnabled( …
Run Code Online (Sandbox Code Playgroud)

java-native-interface android sdl opengl-es admob

5
推荐指数
1
解决办法
2949
查看次数

删除对象并在同一内存位置再次创建

当我用delete运算符删除某个对象,然后再用new运算符创建时,在同一个内存位置创建对象的保证是什么?

一些例子:

Object* obj = new Object(5);
delete obj;
Object* obj = new Object(2);
Run Code Online (Sandbox Code Playgroud)

c++ memory new-operator

4
推荐指数
2
解决办法
724
查看次数

如何退出安卓 NDK 应用程序

我正在像this answer一样在C++中使用Android NDK制作自己的断言宏,但是有一个std::exit功能无法在Android中使用。有没有像std::exitAndroid一样的替代品?

c++ exit android-ndk

4
推荐指数
1
解决办法
3200
查看次数

Opengl加载矩阵

如果我想在OpenGl中构建翻译矩阵,我必须这样做:

float f[16] =
{
    1,0,0,1,
    0,1,0,2,
    0,0,1,3,
    0,0,0,1
};

glLoadMatrixf(f);
Run Code Online (Sandbox Code Playgroud)

要么

float f[16] =
{
    1,0,0,0,
    0,1,0,0,
    0,0,1,0,
    1,2,3,1
};

glLoadMatrixf(f);
Run Code Online (Sandbox Code Playgroud)

行列还是列行?

opengl matrix

2
推荐指数
1
解决办法
1135
查看次数

Operator()作为Matrix类的下标

通过这个站点C++ FAQ我已经为我的Matrix类重载了一个operator().这是我的班级:

class Matrix
{
    public:
    inline float& operator() (unsigned row, unsigned col)
    {
        return m[row][col];
    }

    private:
    float m[4][4];
};
Run Code Online (Sandbox Code Playgroud)

现在我可以在主函数中使用它,如下所示:

int main()
{
    Matrix matrix;
    std::cout << matrix(2,2);
}
Run Code Online (Sandbox Code Playgroud)

但现在我想用它像这样的指针:

int main()
{
    Matrix matrix;
    Matrix* pointer = &matrix;
    std::cout << pointer(2,2);
}
Run Code Online (Sandbox Code Playgroud)

和compilator告诉指针不能用作函数.有什么解决方案吗?

c++ operator-overloading matrix

2
推荐指数
1
解决办法
514
查看次数

是Mesa3d CPU还是GPU?

Mesa是否使用CPU进行渲染是真的吗?A已阅读有关Mesa的内容,但仍无法理解它的真正工作原理

opengl cpu gpu mesa

0
推荐指数
1
解决办法
778
查看次数