views:

68

answers:

1

I have a C++ object that I'm getting the reference to in my view controller like this:

m_applicationEngine = (ApplicationEngine *)[(GLView *)[self.parentViewController view] m_applicationEngine];

In my location delegate I call a methid in the class like this:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation       *)newLocation fromLocation:(CLLocation *)oldLocation {
 CLLocationCoordinate2D coordinate = [newLocation coordinate];

 NSLog(@"Location acquired %f, %f", coordinate.latitude, coordinate.longitude);
 myLocation = new Location(coordinate.latitude, coordinate.longitude);

 m_applicationEngine->GotoLoc(myLocation);
 }

It does call the GotoLoc function but it crashes the first time the function accesses a public member variable of the m_applicationEngine instance. I'm positive the member has already been initialized. Anyone have any ideas?

m_applicationEngine is a C++ object initialized in initWithFrame() in GLView:UIView.

m_applicationEngine = new ApplicationEngine(m_renderingEngine, self);

Here's the code of GotoLoc(). The first time it references m_rotation which is a member variable of the class it crashes. I can call GotoLoc() in other areas of the code, just not in the above Obj-C delegate function.

void ApplicationEngine::GotoLoc(Location *location) {
vec3 eye = vec3(0, 0, 1);
vec3 end = location->loc;

// Compute the difference between where we're looking at now vs. where we want to point
mat4 transpose;
MatrixTranspose(transpose, m_rotation);
MatrixVec3Multiply(eye, eye, transpose);

//cout << "Inverse.  I was here x:" << relativeVec.x << " y:" << relativeVec.y << " z:" << relativeVec.z << endl;

// bring vectors down to the equator to measure x angle
vec3 relativeX = vec3(eye.x, 0, eye.z);
// reference vector is the rotation axis for the sign to be correct
float xAngle = signed_angle(relativeX, vec3(end.x, 0, end.z), vec3(0,-1,0));

mat4 rotationX;
MatrixRotationY(rotationX, -1 * xAngle);
MatrixMultiply(m_rotation, rotationX, m_rotation);

// need to rotate eye vector to line up on y with new target to measure y angle
MatrixTranspose(transpose, rotationX);
MatrixVec3Multiply(eye, eye, transpose);
float yAngle = signed_angle(eye, end, vec3(1,0,0));

cout << "Went to difference of: ANGLE x: " << RADIANS_TO_DEGREES(xAngle) << " y:" << RADIANS_TO_DEGREES(yAngle) << endl;

mat4 rotationY;
MatrixRotationX(rotationY, -1 * yAngle);
MatrixMultiply(m_rotation,  m_rotation, rotationY);

}

A: 

Best guess on the information you have given us is that m_applicationEngine is actually not a C++ object. Where do you create it? in init? in the accessor m_applcationEngine?

If you want a better answer than that, show us the code of GotoLoc() and how you init the C++ object.

Edit (following new posted code):

I think m_applicationEngine is null. You should be able to confirm that by putting a break on the first line of GotoLoc() and checking the this (is that right for C++? I want the equivalent to self) pointer.

If your view is in a nib file, I have a feeling initWithCoder: is used instead of initWithFrame: which would explain why your C++ object is never constructed. The easiest way to fix this is to create and access it through a property and initialise it on first use e.g.

// .h file

@property (readonly, assign) ApplicationEngine* applicationEngine;

//  .m file

-(ApplicationEngine*) applicationEngine
{
    if (m_applicationEngine == NULL)
    {
        m_applicationEngine = new ApplicationEngine(m_renderingEngine, self);
    }
    return m_applicationEngine;
}
JeremyP
Thanks for the response. I updated my question with the code you asked for.
mm1
Thanks for the help. I figured it out, self.parentViewController in the top line of code was nil so I never got a valid pointer to m_applicationEngine.
mm1