OpenVR Teleportation Problem (Forward direction calculation) - rotation

So I am trying to implement teleportation in my VR application (not in Unity). I am able to get the pose matrices for each controller from
if (auto error = vr::VRInput()->GetPoseActionDataForNextFrame(hand[eHand].pose_handle, vr::TrackingUniverseStanding, &poseData, sizeof(poseData), vr::k_ulInvalidInputValueHandle) != vr::VRInputError_None
|| !poseData.bActive || !poseData.pose.bPoseIsValid)
{
std::cerr << "pose invalid " << error << std::endl;
}
else
{
hand[eHand].pose = ConvertSteamVRMatrixToMatrix4(poseData.pose.mDeviceToAbsoluteTracking);
}
I then use glm::decompose() to get the position and orientation (orientation must be conjugated). Then I try to get the forward direction from it by multiplying the orientation matrix by vec4(0,0,1,0) but the resultant vector is incorrect. Is there a flaw in my logic?

So it turns out I had a few issues with my methodology. Firstly, OpenVR defines the forward direction of the controllers as vec4(0,0,-1,0), and secondly, it is defined with respect to the HMD camera. In order to move around the scene, I use a second camera matrix for translation and rotation. Thus had to take this into account.
My final calculation is as follows
auto forward = glm::normalize(glm::inverse(nonHMDViewMat) *
vr.GetControllerPose(Right) * glm::vec4(0,0,-1,0));
Where vr.GetControllerPose(Right) returns the matrix in hand[eHand].pose for the right hand.

Related

Count of nodes in an specific range

I'm using veins 5 and I am trying to obtain the position of nodes around in a certain distance from a node. More specifically, I'm trying to get a mapping position of all nodes in an instant to work with the positions of the nodes.
I read this question How to get count of cars in specific range, however it centered in veins 4.6 and also I didn't get how to use the method suggested by Christoph Sommer. Is it possible to get the mapping in veins 5? How can I work this?
I'll appreciate any help
Thanks!
Finally I got the position of all nodes in the simulation and calculate their distance from a tagged car.
To do this I "translate" the answer of Ahmad Ahsan in the question How to get Coordinates of each vehicle in VEINS? to veins 5.0 in the following way:
void MessageGenerator::getMapping(){
// Get my position on the scenario
veins::Coord myPosition = mobility->getPositionAt(simTime());
EV << myPosition << endl;
// Get all available nodes in simulation
std::map<std::string, cModule*> allNodes = mobility->getManager()->getManagedHosts();
// Iterate through collection and find distance,
std::map<std::string, cModule*>::iterator it;
for(it = allNodes.begin(); it != allNodes.end(); it++)
{
TraCIMobility* auxMobility = TraCIMobilityAccess().get(it->second);
veins::Coord receiverPosition = auxMobility->getPositionAt(simTime());
//returns distance in meters
double dist = myPosition.distance(receiverPosition);
EV << "Distance: " << dist << endl;
}
}
The key change is in the getPositionAt(simTime()) method.
One additional comment, as discussed in this post the method of obtain all vehicles in simulation is a bad practice if this data is used for realistic simulation purposes, because it is rarely possible to obtain all positions in one time step. In my case, I used it for only evaluation purposes.

Rotation between 2 points facing away when standing at back while facing towards while standing infront (pics)

With this little piece of code I've made it possible to rotate the 'monster' towards the avatar but if the avatar is behind the 'monster', the 'monster' is facing away from the avatar. (Pic's below)
Note: the white numbers are the value of m_RotationAngle
DOUBLE2 mousePos = GAME_ENGINE->GetMousePosition();
double xDiff = m_ActPtr->GetPosition().x - mousePos.x;
double yDiff = m_ActPtr->GetPosition().y - mousePos.y;
m_RotationAngle = atan(yDiff, xDiff);
m_ActPtr->SetAngle(m_RotationAngle);
I've tried to fix it with:
if (diff.x < 0)
{
m_RotationAngle = -atan(diff.y / diff.x);
//also tried following but gave and error:
//m_RotationAngle = tan(diff.y / diff.x);
}
else
{
m_RotationAngle = atan(diff.y / diff.x);
}
But this gave the following output:
You are probably looking for atan2(yDiff, xDiff); which computes the arc tangent of yDiff/xDiff using the signs of arguments to determine the correct quadrant, instead of atan (which also require only one parameter).
Be aware that the result is in the range [-π ; +π] radians, not degrees.

Qt 5.5 drawing a pointer

Is there a built in method for drawing an arrow/pointer at the end of a line in Qt?
I know I can draw it myself, but curious to know if there is already a way of doing this, I've search online and couldn't find anything.
I want to be able to rotate the line and the arrow rotates with it.
Below is the image I'm working on:
I would like to draw the arrow at the end of the dashed line, it should rotate with the dash line pointing around from the bottom left.
[edit] In the end I used a polygon and rotated that:
Code to add polygon needle:
Polygon clsMyClass::plygnGetNeedle(QPoint* pptOrigin
,int intRadius
,float fltAngle) {
const int cintNeedleHalfWidth = 4;
QPolygon plyNeedle;
int intX = pptOrigin->x(), intY = pptOrigin->y();
plyNeedle << QPoint(intX - cintNeedleHalfWidth, intY)
<< QPoint(intX, intY + cintNeedleHalfWidth)
<< QPoint(intX + intRadius - cintNeedleHalfWidth, intY)
<< QPoint(intX, intY- cintNeedleHalfWidth);
return QTransform().translate(intX, intY)
.rotate(fltAngle)
.translate(-intX, -intY)
.map(plyNeedle);
}
I don't recall something like this in Qt. As for the position and angle of the arrow - you can easily find those out if you use something like QPainterPath's angleAtPercent() and pointAtPercent() functions.

LibGDX rotation Bodies issue

It is hard to explain the problem so I recorded a video in order to illustrate the issue. [Video here]
I have image in box2d objects (bodies). When user drags an actor the body underneath moves too so that images follow physics. When the body is not fully rotated everything works as expected (drag&drop) but when rotation happens the movement goes crazy making that unwanted effect of infinite rotation.
Here's my approach:
In the constructor:
for(final Brick b : map.list){
stage.addActor(b.img);
Vector3 v = new Vector3(b.box.getPosition().x,b.box.getPosition().y,0);
camera.project(v);
b.img.setPosition(v.x-b.img.getWidth()*0.5f, v.y-b.img.getHeight()*0.5f);
b.img.setOrigin(b.img.getWidth()*0.5f, b.img.getHeight()*0.5f);
b.img.setRotation((float) Math.toDegrees(b.box.getAngle()));
b.img.addListener((new DragListener() {
public void touchDragged (InputEvent event, float x, float y, int pointer) {
float newPosX =b.img.getX() + x;
float newPosY = b.img.getY() + y;
b.img.setPosition(newPosX-b.img.getWidth()*0.5f,newPosY-b.img.getHeight()*0.5f);
b.box.setTransform(newPosX, newPosY, b.box.getAngle());
}
}));
}
Where map.list is a list containing all bodies that can be dragged.
In the render function:
for(final Brick b : map.list){
b.img.setVisible(true);
b.img.setPosition(b.box.getPosition().x-b.img.getWidth()*0.5f, b.box.getPosition().y-b.img.getHeight()*0.5f);
b.img.setOrigin(b.img.getWidth()*0.5f, b.img.getHeight()*0.5f);
b.img.setRotation((float) Math.toDegrees(b.box.getAngle()));
}
Thanks a lot in advance!
I think your problem is that you set the origin for rotation incorrectly.
b.img.setOrigin(b.img.getWidth()*0.5f, b.img.getHeight()*0.5f);
As long as the bodies aren't rotated at all, everything works fine. Assuming that your bodies position is at the center of the bodies, this should actually be
b.img.setOrigin(v.x, v.y);
Try to use the Box2dDebugRenderer to quickly check if the bodies are really moving so weird, or whether you just draw the pictures incorrectly.

How to use Transformation Matrix for SpriteBatch correctly?

I'm new to XNA and would like to develop a light-weight 2D engine over it, with the entities organized into parent-child hierarchy. I think of matrix when drawing children, because their position, rotation and scale are depend on their parent.
If I use SpriteBatch.Begin(), my rectangles can be drawn on the screen, but when I change them into:
this.DrawingMatrix = Matrix.Identity;
this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullClockwise, null, this.DrawingMatrix);
nothing is drawn anymore. I even tried new Matrix() or Matrix.CreateTranslation(0, 0, 0) for DrawingMatrix.
My first question is: why doesn't it work? I'm not working with any camera or viewport.
Secondly, before drawing an entity, I call the PreDraw to transform the matrix (I will then reset to original state at PostDraw):
protected virtual void PreDraw(Engine pEngine)
{
pEngine.DrawingMatrix *=
Matrix.CreateTranslation(this.X, this.Y, 0) *
Matrix.CreateScale(this.ScaleX, this.ScaleY, 1) *
Matrix.CreateRotationZ(this.Rotation);
}
Please clarify the correction of above code. And I need to scale not at the origin, but at ScaleCenterX and ScaleCenterY, how can I achieve this?
ADDED: Here is an example of my engine's draw process:
Call these code:
this.DrawingMatrix = Matrix.CreateTranslation(0, 0, 0);
this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullClockwise, null, this.DrawingMatrix);
Call PreDraw(), with is:
protected virtual void PreDraw(Engine pEngine)
{
pEngine.DrawingMatrix *=
Matrix.CreateTranslation(this.X, this.Y, 0) *
Matrix.CreateScale(this.ScaleX, this.ScaleY, 1) *
Matrix.CreateRotationZ(this.Rotation);
}
Call Draw(), for example, in my Rect class:
protected override void Draw(Engine pEngine)
{
pEngine.SpriteBatch.Draw(pEngine.RectangleTexture, new Rectangle(0, 0, (int)this.Width, (int)this.Height), new Rectangle(0, 0, 1, 1), this.Color);
}
If I replace above Begin code with this.SpriteBatch.Begin(), the rectangle is drawn correctly, so I guess it is because of the matrix.
First issue is a simple bug: The default for SpriteBatch is CullCounterClockwise, but you have specified CullClockwise causing all your sprites to get back-face-culled. You can pass null if you just want to use the default render states - you don't need to specify them explicitly.
(You would need to change the cull mode if you used a negative scale.)
To answer your second question: You need to translate "back" to place the scaling origin (your ScaleCenterX and ScaleCenterY) at the world origin (0,0). Transformations always happen around (0,0). So normally the order is: translate sprite origin back to the world origin, scale, rotate, translate to place sprite origin at desired world position.
Also, I hope that your PostDraw is not applying the reverse transformations (you made it sound like it does). That is very likely to cause precision problems. You should save and restore the matrix instead.

Resources