Box2d & Cocos2d properly point of colision - cocos2d-iphone

I have collision detection in my game. Now I need point of collison.
I get it with:
int numPoints = contact.b2contact->GetManifold()->pointCount;
b2WorldManifold worldManifold;
contact.b2contact->GetWorldManifold( &worldManifold );
for (int i = 0; i < numPoints; i++)
{
NSLog(#"%#" NSStringFormCGPoint(ccp(worldManifold.points[i].x,worldManifold.points[i].y));
}
This log shows position but in box2d standards. How I should properly convert it to Cocos2d v2 cords? Because multiply by PTM_RATIO not working very well.
UPDATE
At this moment I came up with this.
b2Manifold* mainfold = contact->GetManifold();
int numPoints = mainfold->pointCount;
for (int i=0; i<numPoints; i++) {
b2ManifoldPoint *p = mainfold->points;
NSLog(#"Dot:%#",NSStringFromCGPoint(ccp(p->localPoint.x * PTM_RATIO, p->localPoint.y * PTM_RATIO);));
}
But that shows correct point only for one body.

I think your first example was correct, but you were not properly converting the points to world points. Something like this might work (I'm not at my computer to test it out, but I think this will give you the right direction anyway.
int numPoints = contact.b2contact->GetManifold()->pointCount;
b2WorldManifold worldManifold;
contact.b2contact->GetWorldManifold( &worldManifold );
for (int i = 0; i < numPoints; i++)
{
b2Vec2 worldPoint = worldManifold.points[i]->GetWorldPoint();
NSLOG(#"(%f,%f)", worldPoint.x*PTM_RATIO, worldPoint.y*PTM_RATIO);
}

Related

Why am I getting Undefined Behavior (EXC_BAD_ACCESS (code=1, address=0x1177c1530)) when I access a position of a matrix (opencv mat) on Xcode

I am trying to develop a c++ program with opencv library on Xcode 9.3, macOS 10.14, using clang. During weeks I've been trying to solve or understand why I am getting an undefined behavior error that sometimes makes my program crash and sometimes not.
I am reading a set of images from different cameras and storing them in a multidimensional array: silC[camera][image]. (images are well stored)
I get this error THREAD 1: EXC_BAD_ACCESS (code=1, address=0x1177c1530) when I do this: currentImage.at(x,y) even the values of currentImage are not the problem nor the image.
I post the code below if there's any chance someone could help me..
vector< vector<Mat> > silC(8,vector<Mat>()); // Store the pbm images separating from different cameras
* I read the images and store them in silC. *
for (int z=0; z < nz; z++) {
for (int y=0; y < ny; y++) {
for (int x=0; x < nx; x++) {
// Current voxel coordinates in the 3D space
float xcoord = x*voxelsize + Ox + voxelsize/2;
float ycoord = y*voxelsize + Oy + voxelsize/2;
float zcoord = z*voxelsize + Oz + voxelsize/2;
for (int camId=0; camId < matricesP.size(); camId++) {
imgId = 0;
currentImage = silC[camId][imgId];
int w = silC[camId][imgId].cols;
int h = silC[camId][imgId].rows;
// Project the voxel from the 3D space to the images
Mat P = matricesP[camId];
Mat projection = P*(Mat_<float>(4,1) << xcoord,ycoord,zcoord,1.0);
//We get the point in homog coord.
float xp = projection.at<float>(0);
float yp = projection.at<float>(1);
float zp = projection.at<float>(2);
// Get the cartesian coord
int xp2d = cvRound(xp/zp);
int yp2d = cvRound(yp/zp);
if(xp2d >= 0 && xp2d < w && yp2d >= 0 && yp2d < h){
// all values are correct! :/
// int value = silC[camId][imgId].at<float>(xp2d, yp2d); // undefined behaviour: crashes sometimes..
int value = currentImage.at<float>(xp2d, yp2d); // undefined behaviour also crashes sometimes..
if(value == 255){
cout << "Voxel okey \n";
}
}
}
}
}
}
EDIT:
The solution posted on comments below is that instead of currentImage.at(xp2d,yp2d) --> currentImage.at(yp2d,xp2d), as cv::Mat access requieres.
BUT, I tried to parallelize the for several times with openMP (#pragma omp parallel for) but it kept crashing. If someone is familiar with parallelize I'll appreciate any help.
the solution is what #rafix07 posted. Thank you very much guys, next time I'll try to focus more.

C++ code for Microsoft Kinect - trying to dynamically allocate array of target positions

So I'm trying to modify the Kinect BodyBasicsD2D code so that a fixed number of "target positions" appear on the screen (as ellipses) for the user to move his hand toward. I'm having trouble creating the initial target positions.
This is my code in the header file for the allocation of the array of target positions (these are a public field of the CBodyBasics class, already built into the original BodyToBasics program):
D2D1_POINT_2F* targetPositions = NULL;
int numTargets = 3;
Then I have a function "GenerateTargetPositions" which is supposed to generate 3, in this case, target positions to be passed into the "DrawTargetPositions" function.
void CBodyBasics::GenerateTargetPositions(D2D1_POINT_2F * targetPositions, int numTargets)
{
targetPositions = new D2D1_POINT_2F[numTargets];
RECT rct;
GetClientRect(GetDlgItem(m_hWnd, IDC_VIDEOVIEW), &rct);
int width = rct.right;
int height = rct.bottom;
FLOAT x;
FLOAT y;
D2D1_POINT_2F tempPoint;
for (int i = 0; i < numTargets; i++) {
x = 1.0f*i*width / numTargets;
y = 1.0f*i*height / numTargets;
tempPoint = D2D1::Point2F(x, y);
targetPositions[i] = tempPoint;
}
}
My DrawTargetPositions function is:
void CBodyBasics::DrawTargetPositions(D2D1_POINT_2F * targetPositions, int numTargets)
{
D2D1_ELLIPSE ellipse;
for (int i = 0; i < numTargets; i++)
{
ellipse = D2D1::Ellipse(targetPositions[i], 50.f, 50.f);
m_pRenderTarget->FillEllipse(ellipse, m_pSilverBrush);
}
}
When I try to run my code, I get the error that both "targetPositions" and "targetPositions[i]" is NULL (and thus my GenerateTargetPositions function must not be working properly). I believe that targetPositions[i] is a struct (a point with x and y values) so I am wondering if this may be the reason for my errors.
I call GenerateTargetPositions and DrawTargetPositions before the main "while" loop in my code so that each function is not being called on each iteration (there are many iterations of through the while loop because this is an interactive Microsoft Kinect, recording one's movements).
Any suggestions and advice would be greatly appreciated. Thanks so much!

SFML createMaskFromColor() not working correctly

I'm creating a game where I have 3 separate objects to display. A floor, a player sprite and multiple crates. Below is the code for all three.
#include <iostream>
#include <fstream>
#include "Game.h"
Game::Game()
{
std::ifstream fileHndl;
fileHndl.open("Assets/mapdata.txt");
fileHndl >> mapCols;
fileHndl >> mapRows;
playerX = mapCols / 2;
playerY = mapRows / 2;
mapData = new int *[mapRows];
for (int i = 0; i < mapRows; i++) {
mapData[i] = new int[mapCols];
}
for (int i = 0; i < mapRows; i++) {
for (int j = 0; j < mapCols; j++) {
fileHndl >> mapData[i][j];
}
}
window.create(sf::VideoMode(1280, 1024), "COMP2501 Demo");
window.setFramerateLimit(5);
playerImage.loadFromFile("Assets/actor.png");
playerImage.createMaskFromColor(sf::Color::White);
playerTexture.loadFromImage(playerImage);
playerTexture.setSmooth(true);
playerSprite.setTexture(this->playerTexture);
floorTexture.loadFromFile("Assets/floor.png");
floorTexture.setSmooth(true);
crateImage.loadFromFile("Assets/crate.png");
crateImage.createMaskFromColor(sf::Color::White);
crateTexture.loadFromImage(crateImage);
crateTexture.setSmooth(true);
mapSprites = new sf::Sprite *[mapRows];
for (int i = 0; i < mapRows; i++) {
mapSprites[i] = new sf::Sprite[mapCols];
}
for (int i = 0; i < mapRows; i++)
{
for (int j = 0; j < mapCols; j++)
{
mapSprites[i][j].setPosition(j * 64, i * 64);
if (mapData[i][j] == 1)
{
mapSprites[i][j].setTexture(this->floorTexture);
}
else
{
mapSprites[i][j].setTexture(this->crateTexture);
}
}
}
}
I'm attempting to remove the white background of all 3 images as they're all .pngs however when doing so I get the following result.
http://i.stack.imgur.com/KG3H2.png
The crates appear to be drawing a black border around themselves. Is there a better way to go about removing the white background on PNGs as textures?
Crate
http://i.stack.imgur.com/DA5Dv.png
In the absence of additional information, this would be my logical chain towards a guess:
Since we see the createMaskFromColor() function work fine for the player model, it's not the error source. Since we see the same code being invoked for the other two objects, the chroma keying is working fine there as well. Hence, the following answer:
There is nothing but the black background behind the crate sprites. The chroma keying works correctly, and happily demonstrates us the black background behind the transparent corners.
How to fix:
Make sure the floor sprite is present behind the crate sprites as well. Maybe create an additional sprite, "crate over a floor", to not overlay them every time such a combination is encountered (no idea if this really affects performance, just a guess.)

Not all of my lines are drawing in sfml vertexArray

So I have been working on a project with a friend but I've hit a dead end with the following code.
// The initial angle (for the first vertex)
double angle = PI / 2;
//double angle=0;
int scale = 220;
int centerX = 300;
int centerY = 250;
// Calculate the location of each vertex
for(int iii = 0; iii < vertices.getVertexCount(); iii++) {
// Adds the vertices to the diagram
vertices[iii].position = sf::Vector2f(centerX + cos(angle) * scale, centerY - sin(angle) * scale);
vertices[iii].color = sf::Color::White;
// Calculates the angle that the next point will be at
angle += q*(TAU / p);
}
// Draws the lines on the diagram
sf::VertexArray lines = sf::VertexArray(sf::Lines, vertices.getVertexCount());
for(int iii = 0; iii < lines.getVertexCount()-1; iii+=2) {
lines[iii] = vertices[iii];
lines[iii+1] = vertices[iii+1];
lines[iii].color = sf::Color(255,(iii)*50,255,255);//sf::Color::White;
lines[iii+1].color = sf::Color(255,(iii+1)*50,255,255);//sf::Color::White;
}
return lines;
The compiler doesn't give any errors but when I run the code exactly half of the lines show up, but only if p is an even number (p is the number of vertices in the polygon.) For example when I try to draw a square p=4 2 lines will show up if I try to draw a pentagon p=5 all of the lines show up.
On a different forum someone suggested adding 0.5f to the coordinates of all vertices to change how openGl rounds. I tried this but it didn't work.
Always provide a screenshot of what you are seeing and a Paint drawing of what you want to achieve
Change
sf::VertexArray lines = sf::VertexArray(sf::Lines, vertices.getVertexCount());
for(int iii = 0; iii < lines.getVertexCount()-1; iii+=2) {
lines[iii] = vertices[iii];
lines[iii+1] = vertices[iii+1];
lines[iii].color = sf::Color(255,(iii)*50,255,255);//sf::Color::White;
lines[iii+1].color = sf::Color(255,(iii+1)*50,255,255);//sf::Color::White;
}
to
sf::VertexArray lines = sf::VertexArray(sf::LinesStrip, vertices.getVertexCount());
for(int iii = 0; iii < lines.getVertexCount(); iii+=1) {
lines[iii] = vertices[iii];
lines[iii].color = sf::Color(255,(iii)*50,255,255);//sf::Color::White;
}
As the primitive type sf::Lines require 2x points than lines you draw. sf::LinesStrip should do the trick in VertexArray.

vtk 6.x, Qt: 3D (line, surface, scatter) plotting

I am working on a Qt (4.7.4) project and need to plot data in 2D and 3D coordinate systems. I've been looking into vtk 6.1 because it seems very powerful overall and I will also need to visualize image data at a later point. I basically got 2D plots working but am stuck plotting data in 3D.
Here's what I tried: I'm using the following piece of code that I took from one of vtk's tests ( Charts / Core / Testing / Cxx / TestSurfacePlot.cxx ). The only thing I added is the QVTKWidget that I use in my GUI and its interactor:
QVTKWidget vtkWidget;
vtkNew<vtkChartXYZ> chart;
vtkNew<vtkPlotSurface> plot;
vtkNew<vtkContextView> view;
view->GetRenderWindow()->SetSize(400, 300);
vtkWidget.SetRenderWindow(view->GetRenderWindow());
view->GetScene()->AddItem(chart.GetPointer());
chart->SetGeometry(vtkRectf(75.0, 20.0, 250, 260));
// Create a surface
vtkNew<vtkTable> table;
float numPoints = 70;
float inc = 9.424778 / (numPoints - 1);
for (float i = 0; i < numPoints; ++i)
{
vtkNew<vtkFloatArray> arr;
table->AddColumn(arr.GetPointer());
}
table->SetNumberOfRows(numPoints);
for (float i = 0; i < numPoints; ++i)
{
float x = i * inc;
for (float j = 0; j < numPoints; ++j)
{
float y = j * inc;
table->SetValue(i, j, sin(sqrt(x*x + y*y)));
}
}
// Set up the surface plot we wish to visualize and add it to the chart.
plot->SetXRange(0, 9.424778);
plot->SetYRange(0, 9.424778);
plot->SetInputData(table.GetPointer());
chart->AddPlot(plot.GetPointer());
view->GetRenderWindow()->SetMultiSamples(0);
view->SetInteractor(vtkWidget.GetInteractor());
view->GetInteractor()->Initialize();
view->GetRenderWindow()->Render();
Now, this produces a plot but I can neither interact with it not does it look 3D. I would like to do some basic stuff like zoom, pan, or rotate about a pivot. A few questions that come to my mind about this are:
Is it correct to assign the QVTKWidget interactor to the view in the third line from the bottom?
In the test, a vtkChartXYZ is added to the vtkContextView. According to the documentation, the vtkContextView is used to display a 2D scene but here is used with a 3D chart (XYZ). How does this fit together?
The following piece of code worked for me. No need to explicitly assign an interactor because that's already been taken care of by QVTKWidget.
QVTKWidget vtkWidget;
vtkSmartPointer<vtkContextView> view = vtkSmartPointer<vtkContextView>::New();
vtkSmartPointer<vtkChartXYZ> chart = vtkSmartPointer<vtkChartXYZ>::New();
// Create a surface
vtkSmartPointer<vtkTable> table = vtkSmartPointer<vtkTable>::New();
float numPoints = 70;
float inc = 9.424778 / (numPoints - 1);
for (float i = 0; i < numPoints; ++i)
{
vtkSmartPointer<vtkFloatArray> arr = vtkSmartPointer<vtkFloatArray>::New();
table->AddColumn(arr.GetPointer());
}
table->SetNumberOfRows(numPoints);
for (float i = 0; i < numPoints; ++i)
{
float x = i * inc;
for (float j = 0; j < numPoints; ++j)
{
float y = j * inc;
table->SetValue(i, j, sin(sqrt(x*x + y*y)));
}
}
view->SetRenderWindow(vtkWidget.GetRenderWindow());
chart->SetGeometry(vtkRectf(200.0, 200.0, 300, 300));
view->GetScene()->AddItem(chart.GetPointer());
vtkSmartPointer<vtkPlotSurface> plot = vtkSmartPointer<vtkPlotSurface>::New();
// Set up the surface plot we wish to visualize and add it to the chart.
plot->SetXRange(0, 10.0);
plot->SetYRange(0, 10.0);
plot->SetInputData(table.GetPointer());
chart->AddPlot(plot.GetPointer());
view->GetRenderWindow()->SetMultiSamples(0);
view->GetRenderWindow()->Render();
You might want read the detailed description in vtkRenderViewBase
QVTKWidget *widget = new QVTKWidget;
vtkContextView *view = vtkContextView::New();
view->SetInteractor(widget->GetInteractor());
widget->SetRenderWindow(view->GetRenderWindow());