gpt4 book ai didi

c++ - 将对象移动到场景中的指定点?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:48:48 25 4
gpt4 key购买 nike

我一直在尝试使用 3dsmax 模型拼凑一个国际象棋游戏。此时,我已经能够导入模型,突出显示我有兴趣移动的所选游戏 block ,并选择我要移动到的方 block 。这是当前状态的屏幕截图:

http://img26.imageshack.us/img26/9555/chessk.png

黑色圆圈代表我点击的地方,你可以看到棋子去了哪里。具体应该去哪里我没有做过具体的计算。每当我用选定的棋子点击棋盘时,它总是朝相同的方向移动。这是因为刚开始时放入了这个虚拟代码:

if ( isObjectSelected && isSquareSelected && moveObject )
{
glPushMatrix();
glTranslatef(0.2f, 0.0f, 0.0f); //PLACEHOLDER-DUMMY CODE
}

glDrawElements( GL_TRIANGLES, pMaterial->triangleCount * 3, GL_UNSIGNED_INT, model.getIndexBuffer() + pMaterial->startIndex );

if ( isObjectSelected && isSquareSelected )
glPopMatrix();

我考虑做的是在模型加载完成后,以某种方式检查棋盘上的哪个方 block 。 Then, when a piece is selected and a "move to"square is selected, find the x,y,z glTranslate3f to move to that center square.

这是最好的方法吗?似乎随着游戏的进行,我将需要单独存储每件作品的 glTranslate。当一 block 从第 2 点到第 3 点时,我应该计算从原始起点到第 3 点的 glTranslate,对吗?

但是您如何确定一个游戏 block 是否占据一个正方形,以及您如何确定两个正方形之间的 glTranslate3f(X, Y, Z)?这是我的 .OBJ 文件中的一个正方形示例

#
# object Square58
#

v -37.1874 18.6313 80.7864
v -67.0955 18.6313 91.4436
v -56.4384 18.6313 121.3513
v -26.5306 18.6313 110.6938
# 4 vertices

vn 0.0000 1.0000 -0.0000
# 1 vertex normals

vt 0.0000 0.0000 0.0000
# 1 texture coords

我假设我需要找到每个正方形的中心,然后说一旦应用程序知道这件作品在 square1 中,并且您点击了 square4,计算平移并开始。我只是不确定如何计算每个正方形的中心,并从 square1-->square4 中找出平移坐标应该是什么。

或者我如何从一开始就确定哪些棋子占据了哪个方格。我可以在加载期间对此进行硬编码,但如果有一种合理的方法来完成此操作,它会帮助我更好地理解。

每个方 block 和游戏 block 都是一个结构 GroupObject,例如:

//A chess piece or square
struct GroupObject
{
std::vector<Material *> materials;
std::string objectName;
std::string groupName;
int index;
std::vector<Vector3 *> vertices;
Vector3 center;
};

Vector3 看起来像:

#ifndef VECTOR3_H
#define VECTOR3_H

#include <math.h>

class Vector3
{
public:
Vector3(float X = 0.0f, float Y = 0.0f, float Z = 0.0f)
{
x = X;
y = Y;
z = Z;
}

Vector3 operator+=(const Vector3 &vec)
{
return (*this = (*this + vec) );
}

Vector3 operator+(const Vector3 &vec)
{
return Vector3(vec.x + x, vec.y + y, vec.z + z);
}

Vector3 operator-=(const Vector3 &vec)
{
return (*this = (*this - vec) );
}

Vector3 operator-(const Vector3 &vec)
{
return Vector3(x - vec.x, y - vec.y, z - vec.z);
}

Vector3 operator*=(float num)
{
return (*this = (*this * num) );
}

Vector3 operator*(float num)
{
return Vector3(x * num, y * num, z * num);
}

Vector3 operator/=(float num)
{
return (*this = (*this / num) );
}

Vector3 operator/(float num)
{
return Vector3(x / num, y / num, z / num);
}

Vector3 operator-(void)
{
//invert direction of vector
return Vector3(-x, -y, -z);
}

float Dot(Vector3 &vec)
{
return (x * vec.x + y * vec.y + z * vec.z);
}

Vector3 operator*(const Vector3 &vec)
{
//cross product
return Vector3( y * vec.z - z * vec.y,
z * vec.x - x * vec.z,
x * vec.y - y * vec.x );
}

float Length(void)
{
//length of vector
return sqrt( x * x + y * y + z * z);
}

Vector3 Normalize(void)
{
float length = Length();
x /= length;
y /= length;
z /= length;

return *this;
}

float Distance(Vector3 &vec)
{
//find distance between two separate vectors
float disX = vec.x - x;
float disY = vec.y - y;
float disZ = vec.z - z;

return sqrt(disX * disX + disY * disY + disZ * disZ);
}

bool operator==(Vector3 &vec)
{
return (vec.x == x && vec.y == y && vec.z == z);
}

bool operator!=(Vector3 &vec)
{
return !(vec == *this);
}

公开: float x, y, z;};

#endif

我打算用它来存储每个正方形的中心,例如:

Vector3 正方形->center = X, Y, Z

希望这会帮助它确定移动到哪里,以及是否有东西占据了那个空间,但我认为我应该得到一些帮助,因为我以前没有这样做过。我也不确定我应该如何计算它,或者仍然完全清楚如何确定一个正方形是否有一个游戏 block 在开始时占据它,或者它是空的。

欢迎任何帮助。谢谢。

更新

现在我在 3ds max 中查看了一个正方形对象属性,它说尺寸为 x: 40.565 y: 40.565

然后我选择了两个正方形,一个在另一个前面。我通过将所有顶点加在一起并除以顶点总和来计算每个顶点的中心。我明白了:

#square 1
x: 111.12125
y: 18.631268
z: 78.286982

#square 2
x: 82.276817
y: 17.615297
z: 88.545845

但是从我原来的例子来看,我可以接近移动到正确位置的唯一方法是移动 glTranslatef(0.2f, 0.0f, 0.0f);

上面列出的两个中心之间的差异要大得多。我正在做一些不正确的事情,但没有看到。

最佳答案

[有点离题]当我编写我的大学项目时,我曾经使用简单的数学公式来确定每条线的交叉点来绘制我的“世界”(它与检查台有相似之处:它是无穷无尽的并且没有颜色区分)。当我得到这些点时,我能够简单地确定哪个特定的方形光标指向哪个。老实说,我使用简单的数学来确定最后(“生产”)版本中的那些中心。

Herethere是我的旧屏幕。

那么,有什么问题呢?当你在做 glPushMatrix() ,您的矩阵重置为默认值 - 位置变为 (0, 0, 0) 并且旋转被重置。如果你想把你的物体放在相交点 {line, plane} ,其中线是从相机原点到光标位置的光线(回想一下 OpenGL 中的相机理论:实际上,屏幕是相机“位置”点前面的平面) 并且飞机是在那条射线前面的东西。 注意:如果您不定义平面 - 您将无法确定交点。

现在,当你得到交点时,就做 glTranslatef(<intersection_point>)然后画出你的棋子或其他任何东西。

如果您对有关如何确定交点的纯代码感兴趣 - 请在评论中通知我。

希望这会有所帮助。

UPD:这是我之前提到的交叉点代码。它使用 sf::Vector3f结构/类 - 它取自 SFML (我将它用于我所有的 GL 项目来处理输入事件并忘记“创建窗口”)。您可以将其定义为具有 3 个 float 的简单结构。函数参数是鼠标光标的坐标。调用它会为您提供交叉点坐标。

sf::Vector3f ScreenToSpace(int x, int y)
{
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;

glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);

winX = (float) x;
winY = (float) viewport[3] - (float) y;
glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

return sf::Vector3f((float) posX, (float) posY, (float) posZ);
}

以下是您应该如何使用它的示例(据我了解您的问题):

sf::Vector3f v = ScreenToSpace(App.GetInput().GetMouseX(), App.GetInput().GetMouseY()); // get global coordinates
v = SpaceToDeskCorrection(v.x, v.y, v.z); // align v to the check-desk cell center

glPushMatrix(); // reset matrix state (incl. position and rotation) and save previous one
glTranslatef(v.x, v.y, v.z); // set matrix position to the intersection point
DrawPawn(); // well, you'll understand this line, right? =)
glPopMatrix();

关于c++ - 将对象移动到场景中的指定点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4775496/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com