I've been trying to make a simple collision system for my 3D game, I'm creating a bounding sphere like this:
struct ACollSphr
{
glm::vec3* pos;
float radius;
};
And in the while loop that renders my game, in main, I give them a position like this:
for (unsigned int i = 0; i < meshModelMatrices2.size(); i++)
{
Ackerfe::ACollSphr tempSphr;
glm::vec3 *temporary = new glm::vec3(meshRenderer2.getBoundingSpherePos(*meshRenderer2.getMesh()) * glm::vec3(vec[i][12], vec[i][13], vec[i][14]));
tempSphr.pos = temporary;
radius = meshRenderer2.getBoundingSphereRadius(*meshRenderer2.getMesh(), *tempSphr.pos);
tempSphr.radius = radius;
meshSphr.push_back(tempSphr);
//std::cout << pos.x << " " << pos.y << " " << pos.z << std::endl;
//std::cout << vec[i][12] << " " << vec[i][13] << " " << vec[i][14] << std::endl;
}
where meshSphr is a vector of spheres and meshRenderer2 is the renderer I use for the meshes I'm loading in, basically I get the mesh, pass it to getBoundingSpherePos and get the position of that mesh, then I multiply it by a glm::vec3 made up of the position values inside the model matrix of each mesh and I get the radius after that and put my newly created sphere inside the meshSphr vector (which I clear after using it for the collision checks so it can get repopulated again in the next iteration)
my collision check looks like this:
for (unsigned int i = 0; i < meshSphr.size(); i++)
{
if (Ackerfe::sphrSphrColl(camera3D.getSphr(), &meshSphr[i]))
{
camera3D.changePosition(camera3D.getPosition()+glm::vec3(-5.0f));
}
}
and my sphrSphrColl function looks like this:
bool sphrSphrColl(ACollSphr *first, ACollSphr *second)
{
if (fabs((first->pos->x - second->pos->x) * (first->pos->x - second->pos->x) +
(first->pos->y - second->pos->y) * (first->pos->y - second->pos->y) +
(first->pos->z - second->pos->z) * (first->pos->z - second->pos->z) < (first->radius + second->radius) * (first->radius + second->radius)))
{
//std::cout <<"DISTANCE: "<<std::endl<<glm::length(*first->pos - *second->pos) << std::endl << std::endl << std::endl << std::endl;
return true;
}
return false;
}
I'm checking the position of the bounding spheres with a cout in my main while loop and the positions are registered correctly but when I pass them to the sphrSphrColl function it only seems to put a bounding sphere in the origin and that's it.
My question: Any idea why it's doing that? While I do have a mesh in the origin why does it only put the bounding sphere there? it's almost like the pointers aren't getting updated when I pass them in the function
Related
I am new to vtk and I am writing an app to draw multiple shapes. The shapes are drawn using point picking event as follow:
void Visualizer::pointPickingEventOccurred (const pcl::visualization::PointPickingEvent &event)
{
std::cout << "[INOF] Point picking event occurred." << std::endl;
float x, y, z;
if (event.getPointIndex () == -1)
{
return;
}
event.getPoint(x, y, z);
std::cout << "[INOF] Point coordinate ( " << x << ", " << y << ", " << z << ")" << std::endl;
points->InsertNextPoint(x, y, z);
}
points here is a vtk point list:
vtkNew<vtkPoints> points;
I am trying to clear points so I can resize it and get new points for each shape but I have not found a way to clear the list.
A simple call to points->Reset() will do the trick.
It will make the object look empty without actually releasing the memory.
Does Initialize() do the trick?
In main, create soldier object
Soldier soldier;
create soldier sprite and set its position
//Load a soldier sprite
sf::Texture texture2;
if (!texture2.loadFromFile(resourcePath() + "soldier.png"))
{
return EXIT_FAILURE;
}
sf::Sprite spriteSoldier(texture2);
spriteSoldier.setPosition(winwidth/2, winheight/2);
spriteSoldier.setOrigin(spriteSoldier.getLocalBounds().width/2,
spriteSoldier.getLocalBounds().height/2);
Load bullet texture for later
//load bullet texture
if(!bulletTexture.loadFromFile(resourcePath()+"Bullet.png")){
return EXIT_FAILURE;
}
Inside while (window.isOpen())
call to processEvents
while(timeSinceLastUpdate > TimePerFrame)
{
timeSinceLastUpdate -= TimePerFrame;
processEvents(window, spriteSoldier, game, soldier, bulletTexture,
elapsedTime);
}
void processEvents(sf::RenderWindow& window, sf::Sprite& spriteSoldier, Game& g, Soldier&
soldier, sf::Texture& bulletTexture, sf::Time elapsed)```
Initially this if statement isn’t entered as there are no bullets in the vector
std::vector tvec = soldier.RetClip();
if ( tvec.size() > 0 )//only enters if created a bullet and added
{
//update position of the bullet, this is the sprite
sf::Vector2f currentpos{};
currentpos = tvec[0].getPosition();
//std::cout <<" currentpos.x before " << currentpos.x << std::endl;
currentpos += (tvec[0].getVelocity() * elapsed.asSeconds());
//std::cout <<" currentpos.x after " << currentpos.x << std::endl;
//set to current position
tvec[0].setPosition(currentpos);
//std::cout <<" currentpos.x after reset " << tvec[0].m_sprite.getPosition().x<<
std::endl;
}
Later on in this function inside
sf::Event event;
while (window.pollEvent(event))
//synch soldier position with its sprite.
soldier.setPosition(spriteSoldier.getPosition());
if (event.key.code == sf::Keyboard::Space)
{
//going to be fired immediately, it's the data that is put into the bulletclass
float currentrotation = (soldier.getRotation() + 90.0); //align bullet with gun
//create sprite
sf::Sprite tempSprite(bulletTexture);//maybe rotate it??
tempSprite.rotate(currentrotation);//keeps this its whole life
tempSprite.Transformable::setPosition(spriteSoldier.getPosition());//start where soldier is
//create a temp bulletclass object to hold sprite details
//BulletClass tempBulletClass(currentrotation, direcNormalised, spriteSoldier.getPosition(), tempSprite);
std::unique_ptr<BulletClass> tempBulletClass ( new BulletClass(currentrotation, direcNormalised, spriteSoldier.getPosition(), tempSprite) );
//add this tempbullet object so the soldier's clip
soldier.addBulletToClip(*tempBulletClass);//hoping they are copying object
}
This creates a bulletclass instance,
this is sent to soldier.addBulletToClip
void Soldier::addBulletToClip(BulletClass& bullet)
{
std::cout <<" bullet added to clip " << std::endl;
BulletClip.push_back(bullet);
}
So the bulletclass instance is added to the std::vector BulletClip;
This all seems ok, BUT BUT BUT when it returns to main and that if statement again …
std::vector<BulletClass> tvec = soldier.RetClip();
if ( tvec.size() > 0 )//only enters if created a bullet and added
{
//update position of the bullet, this is the sprite
sf::Vector2f currentpos{};
currentpos = tvec[0].getPosition();
//std::cout <<" currentpos.x before " << currentpos.x << std::endl;
currentpos += (tvec[0].getVelocity() * elapsed.asSeconds());
//std::cout <<" currentpos.x after " << currentpos.x << std::endl;
//set to current position
tvec[0].setPosition(currentpos);
//std::cout <<" currentpos.x after reset " << tvec[0].m_sprite.getPosition().x<< std::endl;
}
The problem seems to be that whenever this is looped through (once a bullet exists)
This bit of code always states that the x component of the bullet sprite is 1300 (i.e. where the soldier sprite is at and the initial value of the bullet sprite as it was added to the std::vector).
This bit of code does do what is expected and apparently change the value of currentpos based on velocity and elapsed time
currentpos += (tvec[0].getVelocity() * elapsed.asSeconds());
I then want to make sure that currentpos does update the position of the sprite, hence
//set to current position
tvec[0].setPosition(currentpos);
//std::cout <<" currentpos.x after reset " << tvec[0].m_sprite.getPosition().x<< std::endl;
This all seems fine … it does call
sf::Vector2f BulletClass::setPosition(sf::Vector2f in)
{
m_position.x = in.x;//keep local copy
m_position.y = in.y;
std::cout <<" in.x to change x " << in.x << std::endl;
m_sprite.setPosition(in);
std::cout <<" sprite.x now... " << m_sprite.getPosition().x << std::endl;
}
and the checks seem to tell me, yes all is good I’ll update the sprite i’m storing for you …
BUT then next time round, in process events …
std::vector<BulletClass> tvec = soldier.RetClip();
if ( tvec.size() > 0 )//only enters if created a bullet and added
{
//update position of the bullet, this is the sprite
sf::Vector2f currentpos{};
currentpos = tvec[0].getPosition();
//std::cout <<" currentpos.x before " << currentpos.x << std::endl;
the currentxpos is back to the very initial value of 1300, consequently the sprite on the screen never move and is always at the same place just below the feet of the soldier.
This is the code at the bottom of main that draws the bullet
//try and draw the bullets details, stored in the clip
std::vector<BulletClass> temp = soldier.RetClip(); //returns a ref to the clip
for (auto bull = temp.begin(); bull != temp.end(); ++bull)
{
window.draw(bull->returnSprite());
}
window.display();
It seems that any call to process events (ie. updating the bullet position) isn’t kept (it’s like groundhog day - the bullet always starts off at the initial place) …
I have checked that I am sending the soldier object by reference so that any changes to these objects in process events should be permanent
Soldier& soldier
Clearly the soldier object keeps its bullet object in its std::vector (otherwise it wouldn’t keep returning its position of 1300 on x-axis).
So inside the keyboard::space (in void processevents) the soldier object was permanently modified. But inside the if statement (also in void processevents) the soldier object wasn’t permanently modified.
Would appreciate any help as I’m completely stumped.
I want to make a dynamic matrix and assign a values specifically to its index so I have to state the size of the matrix before calling the indices, please see the following code
void Visual_Servoing::Pose_callback(const geometry_msgs::PoseStamped::ConstPtr &msg)
{
Rotations.resize(index + 3,3);
Translations.resize(3, iterator + 1);
std::cout << " #### I'm in Pose_Callback #### " << std::endl;
this->hole_detection(frame);
this->generate_line();
Translation << msg->pose.position.x ,msg->pose.position.y ,msg->pose.position.z;
Translations.col(iterator) = Translation;
std::cout << "iterator =" << iterator << std::endl;
QuatX = msg->pose.orientation.x;
QuatY = msg->pose.orientation.y;
QuatZ = msg->pose.orientation.z;
QuatW = msg->pose.orientation.w;
Rotation << (1 - (2*pow(QuatY,2)) - (2*pow(QuatZ,2))), (2*QuatX*QuatY + 2*QuatW*QuatZ) , (2*QuatX*QuatZ - 2*QuatW*QuatY),
(2*QuatX*QuatY - 2*QuatW*QuatZ) , (1 - (2*pow(QuatX,2)) - (2*pow(QuatZ,2))) , (2*QuatY*QuatZ + 2*QuatW*QuatX),
(2*QuatX*QuatZ + 2*QuatW*QuatY) , (2*QuatY*QuatZ - 2*QuatW*QuatX) , (1 - (2*pow(QuatX,2)) - (2*pow(QuatY,2)));
Rotations.block(index, 0, 3, 3) = Rotation;
std::cout << Translation << std::endl;
std::cout << Translations << std::endl;
std::cout << Rotation << std::endl;
std::cout << Rotations << std::endl;
if (iterator>10)
{
Eigen::MatrixXf VectorsCam(3, theta1.size()); // Matrix contains the vectors in camera frame
VecsinInertial.resize(3, theta1.size());
CirclePosinFrame();
for (int i=0; i<theta1.size(); i++)
{
VecsinInertial.col(i) = Translations.col(i) + Rotations.block(index, 0, 3, 3) * VectorsCam.col(i); // Each Column represents a vector in inertial frame
}
VectorCam = Eigen::MatrixXf::Zero(3, 1);
VectorsCam = Eigen::MatrixXf::Zero(3, theta1.size());
theta1.clear();
theta2.clear();
iterator = 0;
}
iterator = iterator + 1;
index = index + 3;
}
How can I update Translations and Rotations matrices sizes without loosing the already existing values in the matrices ? I already assigned Translations and Rotations in the header file as:
Eigen::MatrixXf Translations; // Matrix of Camera Translations Vectors
Eigen::MatrixXf Rotations;
I've used OpenCV to calibrate my camera from different views and I obtained intrinsics, rvec and tvec with a reprojection error of .03 px (I thus think the calibration is fine).
Now, given one view of my scene, I want to be able to click on a point and find its projection on the other views.
To do so, I se the following functions:
void Camera::project(const vector<cv::Point2f> &pts_2d, vector<cv::Point3f> &pts_3d) {
std::cout << "Start proj 2d -> 3d" << std::endl;
cv::Mat pts_2d_homo;
convertPointsToHomogeneous(pts_2d, pts_2d_homo);
std::cout << "Cartesian to Homogeneous done!" << std::endl;
// Project point to camera normalized coordinates
cv::Mat unproj;
cv::transform(pts_2d_homo, unproj, intrinsics().inv());
std::cout << "Point unprojected: " << unproj.at<cv::Point3f>(0) << std::endl;
// Undo model view transform
unproj -= transVec();
cv::Mat rot;
cv::Rodrigues(rotVec(), rot);
cv::transform(unproj, unproj, rot.t());
unproj *= 1.f/cv::norm(unproj);
std::cout << "Model view undone: " << unproj.at<cv::Point3f>(0) << std::endl;
for (int i = 0; i < unproj.rows; ++i) {
std::cout << "Inside for :" << unproj.at<cv::Point3f>(i,0) << std::endl;
pts_3d.push_back(unproj.at<cv::Point3f>(i,0));
}
}
void Camera::project(const vector<cv::Point3f> &pts_3d, vector<cv::Point2f> &pts_2d) {
cv::projectPoints(pts_3d, rotVec(), transVec(), intrinsics(), dist_coeffs(), pts_2d);
}
Now I have mixed feelings about what I get as an output. When I draw the point projected on each view, they all correspond BUT no matter where I clicked at first in the "canonical view", the projected point is always the same.
Ive succesfully parsed the iqe (Inter Quake Exporter) format and now im stuck at displaying it in bindpose.
All vertices have a weird transformation, where root bone(which covers the full mesh for orientation) is not the only bone with influence for that vertex. You can see it at the arm / should / neck area of the mesh. This mesh has 3 bones. One root bone overing the whole mesh and two arm bones.
You can see how the mesh should look like in the background (exported as obj)
For better understanding, i have the following system:
1. I load all vertex data into one big vbo
(vertices, uvs, normals, tangent, bitangent, boneIndicies(4) (index of joint list) and boneWeights(4))
2. I add all joints to a joint list and create a tree system (simple linked list with position, rotation and parent pointer)
3. i have a seperate list called boneMatrices where i store.. well my bone matrices. currently every frame, later i will precalculate the matrices for each animation frame.
I try to calculate the bone matrix the following way:
for (int i = 0; i < this->jointList.size(); i++)
{
pixel::CJoint *joint = this->jointList.at(i);
std::cout << "Joint ------- " << joint->name << " -------- values: \n";
std::cout << "Translation: " << joint->position.x << " " << joint->position.y << " " << joint->position.z << "\n";
std::cout << "Quaternion: " << joint->rotation.x << " " << joint->rotation.y << " " << joint->rotation.z << " " << joint->rotation.w << "\n";
pixel::matrix4 rotation = pixel::CMatrix::fromQuaternion(joint->rotation);
pixel::matrix4 offset = pixel::CMatrix::translateMatrix(joint->position);
pixel::matrix4 baseMatrix = rotation * offset; // translation * rotation
joint->bindPose = baseMatrix;
joint->invBindPose = pixel::CMatrix::inverseMatrix(baseMatrix);
if (joint->parent != NULL)
{
std::cout << "Joint: " << joint->name << " is child of " << joint->parent->name << " \n";
joint->bindPose = joint->bindPose * joint->parent->invBindPose;
joint->invBindPose = pixel::CMatrix::inverseMatrix(joint->bindPose);
}
std::cout << "\n";
}
I store the transposed (else the mesh is upside down) of joint->invBindPose in the boneMatrices and send it to the shader:
boneMatrix is a std::vector of matrix4
this->material.setParameter("boneMatrix", this->boneMatrices.at(0), this->boneMatrices.size());
The root bone bind calculation has to be right (at least i think) because the head is at the right place and the eyes too (which dont have a bone influence currently)