Вращение вокруг объекта
Пытаюсь заставить камеру вращаться вокруг объекта. Применяю тот же подход, если бы вокруг какого-то кубика вращалась сфера, к примеру. То есть делаю пивот, позиционирую его в точку, где находится кубик, устанавливаю для сферы парент - пивот и при вращении камеры вращаю пивот. Только вот правильое вращение получается только по горизонтали, по вертикали камера двигается по окружности.
Как бы сделать все правиьно? :dontknow: Поиском нашел похожую тему, в которой не разобрался http://forum.boolean.name/showthread.php?t=8539 (глюки камеры и вращения перса). Гугл приподнес мне статьи по преобразовании матриц Direct3D.
Помогите плиз.
Пока все выглядит примерно так.
EntityParent camera, pivot
RotateEntity pivot, camya, camxa, 0.0
Подумал, что потребуется весь код, поэтому перенес тему из другого раздела сюда, потом что пишу с использованием Xors3D не на Blitz3D.
(Если использовать xRotateEntity(pivot, camya, camxa, 0.0), то камера вращается по кругу. Место вращение пивота отметил комментарием. Чтобы перейти в режим вращения вокруг объекта нужно нацелиться на сферу и нажать F и можно нажать G, чтобы отменить режим);
Код:
// include Xors3d Engine header
#include <xors3d.h>
#include <iostream>
#include <math.h>
// for camera mouse look
float CurveValue(float newvalue, float oldvalue, float increments)
{
if(increments > 1.0f) oldvalue = oldvalue - (oldvalue - newvalue) / increments;
if(increments <= 1.0f) oldvalue = newvalue;
return oldvalue;
}
// program entry point
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR commandLine, int commandShow)
{
//initialization
xGraphics3D(800, 600, 32, false, true);
//creating the camera
int camera = xCreateCamera();
xPositionEntity(camera, 0, 0, 0);
//enabling antialiasing
xAntiAlias(true);
//setting texture filtering mode
xSetTextureFiltering(TF_ANISOTROPICX16);
// for mouse look
xMoveMouse(xGraphicsWidth() / 2, xGraphicsHeight() / 2);
float mousespeed = 0.1;
float camerasmoothness = 4.5;
float mxs = 0.0f;
float mys = 0.0f;
float camxa = 0.0f;
float camya = 0.0f;
Handle starmap = xCreateSphere();
xFlipMesh(starmap);
xScaleEntity(starmap, 10, 10, 10);
xEntityOrder(starmap, 16000);
//Handle starmaptex = xLoadTexture("starmap.png");
//xEntityTexture(starmap, starmaptex);
for (int i = 0; i < 100; ++i)
{
float x, y, z;
x = rand()%1000 - 500;
y = rand()%1000 - 500;
z = rand()%1000 - 500;
Handle sph;
xPositionEntity(sph = xCreateSphere(), x, y, z);
xEntityPickMode(sph, PICK_SPHERE, 1, false);
//xScaleEntity(sph, 10, 10, 10);
}
xCameraFogMode(camera, FOG_LINEAR);
xCameraFogRange(camera, 600, 900);
xEntityFX(starmap, FX_FULLBRIGHT | FX_DISABLEFOG);
xSetFont(xLoadFont("Tahoma", 8, true));
bool picked = false;
Handle pickedentity = 0;
Handle pivot = xCreatePivot();
// main program loop
while(!xKeyHit(KEY_ESCAPE))
{
// camera control
if(xKeyDown(KEY_W)) xMoveEntity(camera, 0, 0, 1);
if(xKeyDown(KEY_S)) xMoveEntity(camera, 0, 0, -1);
if(xKeyDown(KEY_A)) xMoveEntity(camera, -1, 0, 0);
if(xKeyDown(KEY_D)) xMoveEntity(camera, 1, 0, 0);
mxs = CurveValue(xMouseXSpeed() * mousespeed, mxs, camerasmoothness);
mys = CurveValue(xMouseYSpeed() * mousespeed, mys, camerasmoothness);
camxa = fmodf(camxa - mxs, 360.0f);
camya = camya + mys;
//if(camya < -89.0f) camya = -89.0f;
//if(camya > 89.0f) camya = 89.0f;
xMoveMouse(xGraphicsWidth() / 2, xGraphicsHeight() / 2);
if (pickedentity != 0)
{
//xPositionEntity(camera, xEntityX(pickedentity) + 50 * sin(camxa), xEntityY(pickedentity) + 50 * cos(camxa), 0.0);
// ВОТ ТУТ ВРАЩАЮ ПИВОТ
//xRotateEntity(pivot, camya, 0.0, 0.0);
xRotateEntity(pivot, 0.0, camxa, 0.0);
xPointEntity(camera, pickedentity);
}
else
xRotateEntity(camera, camya, camxa, 0.0);
xPositionEntity(starmap, xEntityX(camera), xEntityY(camera), xEntityZ(camera));
if (xKeyDown(KEY_F))
{
if (pickedentity != 0) xEntityColor(pickedentity, 255, 255, 255);
pickedentity = xCameraPick(camera, xMouseX(), xMouseY());
if (pickedentity != 0)
{
xPositionEntity(pivot, xEntityX(pickedentity), xEntityY(pickedentity), xEntityZ(pickedentity));
xEntityParent(camera, pivot);
}
}
else if (xKeyDown(KEY_G))
{
if (pickedentity != 0) xEntityColor(pickedentity, 255, 255, 255);
pickedentity = 0;
xEntityParent(camera, 0);
}
if (pickedentity != 0) xEntityColor(pickedentity, 0, 255, 0);
xRenderWorld();
//fps output
char buffer[128];
sprintf(buffer, "FPS: %i", xGetFPS());
xText(10, 10,buffer);
sprintf(buffer, "TrisRendered: %i", xTrisRendered());
xText(10, 30, buffer);
xText(10, 60, "Up\\Down\\Letf\\Right - rotate camera");
xText(10, 80, "W\\A\\S\\D - move camera");
sprintf(buffer, "pos: %i, %i, %i", xEntityX(camera), xEntityY(camera), xEntityZ(camera));
xText(10, 100, buffer);
sprintf(buffer, "picked entity %i", int(pickedentity != 0));
xText(10, 120, buffer);
sprintf(buffer, "mouse x, y %i, %i", xMouseX(), xMouseY());
xText(10, 140, buffer);
//drawing
xFlip();
}
return 0;
}
|