Login Action Required

The NinevehGL Forum uses a new concept of "socialized forum" or as we like to say "Tweet Forum".


Here is the deal:
  1. No new registration is required. Just sign in with your Twitter account and authorize the NinevehGL Forum.
  2. Once you’re in, you'll be able to "Follow a Thread", that means every time that thread receive a new post or update you'll receive a mention on your twitter.
  3. Besides, you can enable "Auto Share", then every new post and/or thread you make will be tweeted on your timeline. (By default, auto-share is enabled only for your threads)

Forum Rules:

1. We understand human comunication can become "hot" sometimes. So some insults and bad words ARE allowed. Just don't push too much being an asshole all the time.

2. SPAMMERS are not allowed. There are penalties for this kind of user and they can be banned forever.

3. You can report other users, if you judge necessary. An user reported many times by many people can also be banned forever. However you can also receive penalties for report deliberately for no apparent reason.

If there is a similar thread title, make sure the other one doesn't already have the answer you're looking for.

This forum uses the BBCode (Bulletin Board Code), here are some instructions:

Bold: [b]text[/b]
Italic: [i]text[/i]
Underline: [u]text[/u]

Code: [code]text[/code]
Quote:
[quote=@username]text[/quote]
[quote]text[/quote]

List:
[ul] [*]item [/ul]
[ol] [*]item [/ol]

URL:
[url]http://url.com[/url]
[url=http://url.com]text[/url]

Image:
[img]http://imageurl.com[/img]

Embed (videos, code, 3D):
[embed]http://url.com[/embed]

Welcome to the NinevehGL's world!
NinevehGL is a 3D engine forged with pure Obj-C.
Welcome to the
Forum!
Hello, Guest.

Your current vote:

You can change your vote many times. But it's still one single vote.

Open Collision Library for NinevehGL
Vote this thread:


@adameisfeld

Posts: 41

NGLUser

Sun, Jun 3 2012


NinevehGL is a fantastic engine, but it isn't finished yet. I understand a lot of people are interested in getting some degree of collision detection working in their apps, including detecting if the user is touching or tapping on an NGLMesh.

I have written a set of classes to handle doing this for the time being until Nineveh's physics API is complete.

Disclaimer: I believe I've done a fairly good job at optimizing things, but I'm positive there are still many places that further optimizations can be made. All this is meant to be is a sort of "kick start" for those of you that are wondering how collision can be implemented. I encourage you to modify it, learn from it, and improve it to your own needs. I require no credit for this code, feel free to use it in commercial or non-commercial apps, or wherever else you want.

An .xcodeproj containing the classes along with a working example of both object-to-object collision and tap location-to-object collision can be found on my site here:

http://mynameisadam.net/AEGLEngine.zip

There is a README included that briefly explains how things work, but I think the example explains itself for the most part. Feel free to ask any questions here and I will reply when I see them.

NOTE: After moving or rotating an AEGLMesh, you must call the updateMesh method on it before attempting to detect collision. This method causes the AEGLMesh to reorient it's bounding box to the mesh's new position and rotation.

List of methods you may find useful:

Methods on AEGLMesh:

  • - (BOOL)isCollidingWithAEGLMesh: (AEGLMesh*) setMesh;

  • Returns YES if the provided mesh is colliding with the mesh being sent the method to.


Methods on AEBoundingBox:

  • - (BOOL)isCollidingWithBoundingBox: (AEBoundingBox*)secondBox;

  • Returns YES if the provided bounding box is colliding with the box being sent the method to.


  • - (BOOL)isCollidingWithAEGLMesh: (AEGLMesh*)secondMesh;

  • Returns YES if any of the bounding boxes belonging to the provided AEGLMesh are colliding with the box being sent the method to.


Methods on AEGLManager:

  • - (NGLvec3)pickScreenAtX: (float)x Y: (float)y forDistance: (float)distance;

  • Returns an NGLvec3 containing the x, y and z position in 3D of the specified 2D coordinates at the specified distance.


  • - (BOOL)collisionBetweenAEGLMeshA: (AEGLMesh*)meshA andAEGLMeshB: (AEGLMesh*)meshB;

  • Returns YES if the two provided AEGLMeshs are colliding.


  • - (AEGLMesh*)didTapMeshInArray: (NSArray*)meshArray atViewLocation: (CGPoint) touchLocation;

  • Returns the first detected AEGLMesh that lays under the provided CGPoint location on the screen. (You may want to alter this to return the closest detected mesh instead of the first mesh detected).


- Adam Eisfeld
0% like this - 0/0

@dineybomfim

Posts: 571

NGLAdmin

Sun, Jun 3 2012



In response to: @adameisfeld

Hey Adam,

Nice work man! Thanks for sharing. I'm sure the people will like and use it while the NinevehGL doesn't offer full support for that.

If you accept some suggestions:


  • Instead of changing the mesh material and recompiling it, which is expensive, prefer just change the material color on the fly. This is a small tip that works only to scalar values, not textures.
  • Instead of creating an entire new class to AEGLMesh, prefer subclassing NGLMesh. This can be much more easy to manipulate than using the "mesh" property inside the AEGLMesh.



Here is the code for changing the material's color in your example:

- (void)handleTap: (UITapGestureRecognizer*)recognizer
{
[(NGLMaterial *)box1.mesh.material setAmbientColor:materialDefault.ambientColor];
[(NGLMaterial *)box2.mesh.material setAmbientColor:materialDefault.ambientColor];

CGPoint tapLocation = [recognizer locationInView:glView];
AEGLMesh *hitMesh = [glManager didTapMeshInArray:meshArray atViewLocation:tapLocation];
if (hitMesh) {
[self didTapAEGLMesh:hitMesh];
}
}

- (void)didTapAEGLMesh: (AEGLMesh*)tappedMesh
{
[(NGLMaterial *)tappedMesh.mesh.material setAmbientColor:materialHit.ambientColor];
}


Good job!
0% like this - 0/0

@adameisfeld

Posts: 41

NGLUser

Sun, Jun 3 2012


In response to: @dineybomfim

Hey thanks, in response:

- The entire part about setting the material of the mesh was just for demonstration purposes only. I just added that to give some visual feedback so people can see whats going on, it serves no other purpose and yes I agree, I wouldn't do that myself if it was for an actual project.

- A while ago (a month or two) I had subclassed NGLMesh and added the functionality that way but ran into problems with calling copyMesh on the NGLMesh. I forget what the exact issue was but Im sure it was likely my fault. Regardless, if people wish to subclass NGLMesh instead then thats perfectly acceptable too. Like I said, my main goal here was just to show people the "behind the scenes" methodology for getting something up and running.

Thanks again though and keep up the great work.
- Adam Eisfeld
0% like this - 0/0

@adameisfeld

Posts: 41

NGLUser

Sun, Jun 3 2012


One other note I forgot to mention:

The way I've handled detecting if a mesh lays under neath a 2D position is done via a single bounding-box check against a set of AEGLMeshs. If you look in the AEGLManager files, you'll see it has it's own single AEBoundingBox entity called touchBox. This touch box is 1000 units long down the z axis, and 0.2 units along the x and y axis. So in order to change the "thickness" of the box used to detect selection, you just need to increase or decrease the x and y values of the touchBox's dimensions (set inside of the init method for AEGLManager). To change the range of the hit detection, increase the touchBoxe's z size. However if you do wish to change the range of the hit detection, remember to also go into the AEGLManager's method:

- (AEGLMesh*)didTapMeshInArray: (NSArray*)meshArray atViewLocation: (CGPoint) touchLocation


And modify the value passed to the call:

[touchBox updateWithStartLocation:startPosition toEndLocation:endPosition withMiddleDistance:500 usingDummyObject3D:dummy];

for withMiddleDistance. This value should always be half of whatever size you make the touchBox's z size.

- Adam Eisfeld
0% like this - 0/0

@kimledev1

Posts: 1

NGLNewbie

Thu, Sep 20 2012


In response to: @adameisfeld

Hey all, I've been using this AEGL touch library, and it works great. I'd like to point out a bug, so other people don't run into the same issue I did and spend 6 hours debugging it

Touch events were working fine for my debug configuration builds, but not ad-hoc builds. If you set the build configuration of an app to debug, a lot of variables are automatically initialized to 0/nil/null if you don't manually do it yourself, but in release build configurations this isn't necessarily the case.

In AEGLManager.m, line 26, when the manager is initialized, the manager is given a bounding box with touchBoxPosition and touchBoxDimensions. touchBoxPosition is never initialized, which means on debug builds it is set to x=0, y=0, z=0 by default, but in my ad-hoc builds it was getting set to x=1000, y=0, z=0. This threw off the hit detection for the whole manager. When I manually initialized that vector to 0, it worked fine.

Hope this helps other people in the future!

- Chris Combs
100% like this - 1/1

@germangda

Posts: 7

NGLNewbie

Mon, Dec 3 2012


In response to: @adameisfeld

Hey Adam nice add to the framework! I am using your touch functions and so far they have been working except for one thing, I am using an NGLGroup3D to handle groups of objects the thing is that when I do some rotation on the group the bounding box is not updating to the new position I read that I need to call the method updateMesh on drawView every time I do some rotation, but it doesn't seem to work I am not using @properties for every AEGLMesh but instead I am loading them dynamically here is the code that I use to init meshes.


- (void)initMeshes
{
_group = [[NGLGroup3D alloc] init];

// Properties for male mesh
NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
kNGLMeshCentralizeYes, kNGLMeshKeyCentralize,
@"0.5", kNGLMeshKeyNormalize,
nil];

// Creating the male mesh
_maleMesh = [[NGLMesh alloc] initWithFile:@"male_mesh_provisional.obj" settings:settings delegate:nil];
_maleMesh.z = 0.00;
_maleMesh.tag = 200;
[_group addObject:_maleMesh];

// Create first sphere mesh
NGLMesh *esfera = [[NGLMesh alloc] initWithFile:@"esfera_escala_.003.obj" settings:nil delegate:nil];
esfera.material = [NGLMaterial materialTurqoise];
[esfera compileCoreMesh];

int numberOfPoints = 0;
// Dynamically adding meshes to group by copying structure of the sphere created
for (int i = 0; i < ([_puntosCabeza count]); i ) {
NSDictionary *xyz = (NSDictionary *)[_puntosCabeza objectAtIndex:i]; // I had initialized this values in other method
NGLMesh *sphere = [esfera copy];
sphere.x = [[xyz objectForKey:@"x"] floatValue];
sphere.y = [[xyz objectForKey:@"y"] floatValue];
sphere.z = [[xyz objectForKey:@"z"] floatValue];
sphere.tag = i;
[_group addObject:sphere];
numberOfPoints = 1;
}

// Setting group properties
_group.z = 0.0f;
[_group setPivot:(NGLvec3){0.0f, 0.0f, 0.0f}];

// glManager for touch events
glManager = [[AEGLManager alloc] initWithCamera:_camera forNGLView:_ninevehGLView];

// Dummy object
NGLObject3D *dummy = [[NGLObject3D alloc] init];

// Touchable boxes array
meshArray = [[NSMutableArray alloc] init];

// Initializing the first mesh, box1 is an AEGLMesh and is a property (strong, nonatomic) var
box1 = [[AEGLMesh alloc] initWithMesh:esfera andDummyObject:dummy];
NGLvec3 dimension;
dimension.x = TAMANO_ESFERA;
dimension.y = TAMANO_ESFERA;
dimension.z = TAMANO_ESFERA;

// Loading all meshes as touchable meshes dynamically except for the male mesh that has tag 200
for (int i = 0; i < numberOfPoints; i ) {
NGLMesh *mesh = (NGLMesh *)[_group objectWithTag:i];
AEGLMesh *box = [[AEGLMesh alloc] initWithMesh:mesh andDummyObject:dummy];
NGLvec3 posicion;
posicion.x = mesh.x;
posicion.y = mesh.y;
posicion.z = mesh.z;
[box addBoundingBoxWithPosition:posicion dimensions:dimension];
[meshArray addObject:box];
}

// Adding gesture recognizer
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[_ninevehGLView addGestureRecognizer:tapRecognizer];
}


This code works the way is supposed to, it adds the meshes to the model and the touches are handled well, the problem is when I rotate the mesh. In the view all the meshes are moved (using the NGLGroup3D) but the touches remain in the same place I mean, the model recognizes a touch on the place that mesh used to be even when that mesh has been moved.

This is where I think I should use the updateMesh method of AEGLMesh.
But I haven't found a way to call it by using a group.
So I tried to generate again the array.


// Called on every render cycle
- (void)drawView
{
_group.rotateY = _position;
_group.z = _distance;
_group.rotateX = _tempPosition;

// I have tried to call update mesh method without success, so I decided to reload ALL the touch array, but also without success. can you point me how to update the touch points?
/*
meshArray = nil;
for (int i = 0; i < [_spheres count]; i ) {
NGLMesh *mesh = (NGLMesh *)[_group objectWithTag:i];
AEGLMesh *box = [[AEGLMesh alloc] initWithMesh:mesh andDummyObject:[[NGLObject3D alloc] init]];
[box addBoundingBoxWithPosition:(NGLvec3){mesh.x, mesh.y, mesh.z}
dimensions:(NGLvec3){TAMANO_ESFERA, TAMANO_ESFERA, TAMANO_ESFERA}];
[meshArray addObject:box];
}
*/

_position = 0.0;
_tempPosition = 0.0;
_distance = 0.0;

[_camera drawCamera];
}


Any help would be really appreciated.
0% like this - 0/0

@adameisfeld

Posts: 41

NGLUser

Mon, Dec 3 2012


In response to: @germangda

Yes this is an issue with the way NinevehGL handles NGLGroups. When you add meshs to an NGLGroup, and rotate or move the group, the meshs inside that group dont get their positions or rotations updated, they remain at whatever they were before you added them to the group.

The solution is to write your own NGLGroup class, to handle rotating and translating groups of NGLMeshs around another NGLObject3D. I had to do this for my app in fact, as I needed the ability to rotate and translate groups of meshs but still have collision detection work.

Translating a group of objects is relatively simple, all you need to do is get the group's original position, then get the group's destination position, then calculate the differences on each axis between the new and original positions (newpos.x - oldpos.x, newpos.y - oldpos.y, newpos.z - oldpos.z), and add these differences to each NGLMesh in the group ([aMesh translateRelativeToX: difference.x y: difference.y z: difference.z]).

Rotation is a little more difficult, but can be achieved by using a few NGLMove commands and some math.

By writing your own implementation of an NGLGroup (not a subclass, just a brand new class), you get the ability to move all of the NGLMeshs in the group and have their positions and rotations update properly. Then you can write a method on the new group class called update that when called will loop through each NGLMesh child of the group updating it's bounding box.
0% like this - 0/0

@germangda

Posts: 7

NGLNewbie

Sun, Jan 6 2013


In response to: @adameisfeld

So I have achieved translation without problem, but I can't achieve rotation, I tried to use the original rotation properties and prior set a pivot in order to rotate relative to this pivot, that works well if the object is in (0,0,0) coordinates, the thing is that for objects that has other coordinates the rotation is more like a translation around some object so I tried 3 approaches:

  1. As the object rotates well in (0,0,0) coordinates I translate the object to (0,0,0) then rotate and then tried to translate back the same distance.
  2. I used the lookAtPointToX:ToY:ToZ: combined with translateRelativeToX:ToY:ToZ: but the results are not the expected.
  3. I tried to use (without success) the NGLMove solution that you propose, the thing is that there is no documentation on how to use it, so I figure out that moveRelativeTo:distance: should be applied to all axis ( x, -x, y, -y, z, -z).

Are all of this equivalent options? Am I right, I mean the logic involved? What I'm sure I'm messing up with the distance calculations So how do I calculate the distance? It would be great if you share your rotation solution, here is the code for what I am trying to achieve.

- (void)setRotateX:(float)rotateX
{
@synchronized(self.nglArray) {

NSEnumerator *e = [self.nglArray objectEnumerator];
NGLMesh *object;
while (object = [e nextObject]) {
// Option A
// [object translateToX:0.0 toY:0.0 toZ:0.0];
// [object setRotateX:rotateX];
// [object translateToX:?? toY:?? toZ:??];

// Option B
// [object lookAtPointX:0.0 toY:0.0 toZ:0.0];
// [object translateRelativeToX:?? toY:?? toZ:??];

// Option C
// [object moveRelativeTo:NGLMoveBackward distance:??];
// [object moveRelativeTo:NGLMoveDown distance:??];
// [object moveRelativeTo:NGLMoveForward distance:??];
// [object moveRelativeTo:NGLMoveLeft distance:??];
// [object moveRelativeTo:NGLMoveRight distance:??];
// [object moveRelativeTo:NGLMoveUp distance:??];
}

super.rotateX = rotateX;

}
}

I think the option A is the best approach and the easiest one but how do I translate it back?
0% like this - 0/0

@germangda

Posts: 7

NGLNewbie

Tue, Jan 8 2013


In response to: @germangda

It seems that was more easy than I thought, check this thread.
http://nineveh.gl/community/forum/rotation_around_an_arbitrari_point
0% like this - 0/0

@bhartiya_varun

Posts: 27

NGLNewbie

Wed, Jan 30 2013


In response to: @germangda

Did you get a chance to write this custom NGLGroup3D class? Would it be possible for you to share the code?
0% like this - 0/0

@ZeronBryan

Posts: 3

NGLNewbie

Tue, Feb 12 2013


In response to: @bhartiya_varun

Hey adam

I'm using AEGLEngine on my little project and it just made my day.
Anyway messing around with it I wanted to implement it on "The island" project sample ,but I cant get glView to apply and I cant figure out why. Would really appreciate if you could give me a quick straight on it.

I apologize for my ignorance. Thanks.
0% like this - 0/0

@NihilistMe

Posts: 7

NGLNewbie

Tue, Nov 19 2013


In response to: @adameisfeld

Hi,

Do we have any update ? because this link is not working ...

Thanks
100% like this - 2/2

@sashah_t

Posts: 27

NGLNewbie

Tue, Nov 26 2013


In response to: @adameisfeld

Hey adameisfeld,

The link at the top of this thread does not seem to work anymore. It seems to be a pretty awesome thing you were sharing on here and would help a lot of people if the link were to be updated.
100% like this - 3/3

@douglasbischoff

Posts: 2

NGLNewbie

Fri, Dec 6 2013


Does anyone have this project, or usable code like it? Someone who downloaded it previously and has it hanging around somewhere that they could re-post?

Many thanks in advance!
100% like this - 2/2

@jjsidhu23

Posts: 2

NGLNewbie

Wed, Dec 11 2013


In response to: @ZeronBryan

Hi ZeronBryan!!

Do you still have the collision detection code that Adam provided? I've been trying to get this to work myself and would love to see how far along his work came. It looks like a number of other users of NINEVEGL are searching around for it as well.

Thanks,
Jat
100% like this - 1/1
Technology

NinevehGL is a 3D engine built right on top of OpenGL ES and it uses all the programmable pipeline power, making it easy for you to create great application with shaders.

Share on


Follow NinevehGL
Fastest way to contact us:

Copyright © 2011 db-in. All rights reserved.