Particles inside a moving Box2d world are getting drawn on top instead of inside a layer - objective-c

I'm using LevelHelper to build my level, and I'm adding some particles (dynamically initialized CCParticleSystemQuad's) inside my level. All works fine until I move the world (it's a dynamically drawn world in Box2D in which I follow the player with the camera). If I move the world, newly added particles,which are emitting continuously, are drawn at the right position but in the particle-animation afterwards the particles seem to be drawn relatively of the global world/screen position. This gives a weird 'trippy' effect which looks totally unrealistic. The particles should be redrawn/refreshed inside the world
LevelHelperLoader * lh = gameLayer.lh;
LHLayer * layer = [lh layerWithUniqueName:#"MAIN_LAYER"];
NSArray * array = [lh spritesWithTag:WORTEL];
CCParticleSystemQuad * particle;
CGPoint position;
for (LHSprite * sprite in array) {
particle = [CCParticleSystemQuad particleWithFile:#"DirtParticles.plist"];
[layer addChild:particle z:0];
position = sprite.position;
position.y += sprite.contentSize.height * 0.5f;
[particle setPosition:position];
[particle resetSystem];
}
Does anybody know what I might be doing wrong?

Try changing the particle position type:
particle.positionType = kCCPositionTypeFree;
The alternatives are kCCPositionTypeRelative and kCCPositionTypeGrouped. You may have to try all to see which of them best fits your scenario, I'm guessing it's either "free" or "relative".

Related

Tile Collision In GML

I am making a game based on the game AZ on the website Y8, and I am having problems with tile collisions.
the player moves basically by giving it speed when up is pressed, then rotating left or right.
direction = image_angle;
if(keyForward)
{
speed = 2;
}
else speed = 0;
// rotate
if(keyRotateLeft)
{
image_angle = image_angle + 5;
}
if(keyRotateRight)
{
image_angle = image_angle - 5;
}
then I said when the player collides with the tile speed = 0. But the player gets stuck and can't move anymore. is there a better way to do this.
A simple approach would be as following:
Attempt to rotate
Check if you are now stuck in a wall
If you are, undo the rotation.
A more advanced approach would be to attempt pushing the player out of solids while rotating.
Alternatively, you may be able to get away with giving the player a circular mask and not rotating the actual mask (using a user-defined variable instead of image_angle).

How to get the real position of a sub node in SceneKit after rotation?

I am developing a scene with SceneKit. I have a main node with a subnode:
// Main node
SCNNode* planet = [SCNNode node];
planet.geometry = [SCNSphere sphereWithRadius:2];
planet.position = SCNVector3Make(0, -3, 5);
// sub-node
SCNNode* satellite = [SCNNode node];
satellite.geometry = [SCNSphere sphereWithRadius:0.4];
satellite.position = SCNVector3Make(4, 0, 0);
[planet addChildNode:satellite];
[scene.rootNode addChildNode:planet];
I use a NSTimer to make some actions and some animations. In the timer event I do that:
planetRotation += 0.1;
planet.rotation = SCNVector4Make(0,1,0, planetRotation);
But if i try to get the position of the satellite node I always get the same value.
I tried to get the positionnode to know the real position of the satellite node but nothing changes.
How can I get the real position of a sub-node when I change the rotation of the parent node?
Thanks in advance
the position of a node is expressed in its parent coordinate system. Just like for views in UIKIt/AppKit. If you change the frame of a view, the frame of its subviews does not change.
What you want is what we call the world transform of the subnode (i.e. its transform expressed in the coordinate system of the scene's root node).
You can have a look at worldTransform and -convertPosition:toNode:.
The node's position won't change due to physics, that is why you aren't seeing it change. You need to call the node's presentationNode to get the position of the node as it is presented onscreen:
node.presentationNode.position

THREE.js rotating camera around an object using orbit path

I am struggling in solving this problem.
On my scene, I have a camera which looks at the center of mass of an object. I have a some buttons that enable to set camera position on particular view (front view, back view,...) along a invisible sphere that surroung the object (constant radius).
When I click on the button, i would like the camera to move from its start position to the end position along the sphere surface. When camera moves I would like it to keep fixing center of mass of the object.
Has anyone have a clue on how to achieve this?
Thanks for help!
If you are happy/prefer to use basic trigonometry then in your initialisation section you could do this:
var cameraAngle = 0;
var orbitRange = 100;
var orbitSpeed = 2 * Math.PI/180;
var desiredAngle = 90 * Math.PI/180;
...
camera.position.set(orbitRange,0,0);
camera.lookAt(myObject.position);
Then in your render/animate section you could do this:
if (cameraAngle == desiredAngle) { orbitSpeed = 0; }
else {
cameraAngle += orbitSpeed;
camera.position.x = Math.cos(cameraAngle) * orbitRange;
camera.position.y = Math.sin(cameraAngle) * orbitRange;
}
Of course, your buttons would modify what the desiredAngle was (0°, 90°, 180° or 270° presumably), you need to rotate around the correct plane (I am rotating around the XY plane above), and you can play with the orbitRange and orbitSpeed until you hare happy.
You can also modify orbitSpeed as it moves along the orbit path, speeding up and slowing down at various cameraAngles for a smoother ride. This process is called 'tweening' and you could search on 'tween' or 'tweening' if you want to know more. I think Three.js has tweening support but have never looked into it.
Oh, also remember to set your camera's far property to be greater than orbitRadius or you will only see the front half of your object and, depending on what it is, that might look weird.

Keeping an object made in OpenGL within the boundaries a window

I have been working on a game using objective c and OpenGL. I know how to create the object and how to make it move the way I want, but I cannot keep it within the window. How do you keep the object within the window?
OpenGL FAQ, section 8.070: How can I automatically calculate a view that displays my entire model?:
The following is from a posting by Dave Shreiner on setting up a basic
viewing system:
First, compute a bounding sphere for all objects in your scene. This
should provide you with two bits of information: the center of the
sphere (let ( c.x, c.y, c.z ) be that point) and its diameter (call it
"diam").
Next, choose a value for the zNear clipping plane. General guidelines
are to choose something larger than, but close to 1.0. So, let's say
you set:
zNear = 1.0;
zFar = zNear + diam;
Structure your matrix calls in this order (for an Orthographic projection):
GLdouble left = c.x - diam;
GLdouble right = c.x + diam;
GLdouble bottom c.y - diam;
GLdouble top = c.y + diam;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(left, right, bottom, top, zNear, zFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
This approach should center your objects in the middle of the window and stretch them to fit (i.e., its assuming that you're using a
window with aspect ratio = 1.0). If your window isn't square, compute
left, right, bottom, and top, as above, and put in the following logic
before the call to glOrtho():
GLdouble aspect = (GLdouble) windowWidth / windowHeight;
if ( aspect < 1.0 ) { // window taller than wide
bottom /= aspect;
top /= aspect;
} else {
left *= aspect;
right *= aspect;
}
The above code should position the objects in your scene appropriately. If you intend to manipulate (i.e. rotate, etc.), you
need to add a viewing transform to it.
A typical viewing transform will go on the ModelView matrix and might
look like this:
gluLookAt(0., 0., 2.*diam,
c.x, c.y, c.z,
0.0, 1.0, 0.0);
a "look at" camera is a very convenient technique to make a viewer track an object (hence however the object or camera point moves, the object will stay onscreen). see 'gluLookAt' for a commonly provided implementation, most 3d helper code libraries will have one. You give it a desired camera point, object of interest, and 'up-vector', and it will create an appropriate world (camera transformation) matrix.
Otherwise if you're in control of the object, just don't move it outside of the initial frustum.

Why do my raytraced spheres have dark lines when lit with multiple light sources?

I have a simple raytracer that only works back up to the first intersection. The scene looks OK with two different light sources, but when both lights are in the scene, there are dark shadows where the lit area from one ends, even if in the middle of a lit area from the other light source (particularly noticeable on the green ball). The transition from the 'area lit by both light sources' to the 'area lit by just one light source' seems to be slightly darker than the 'area lit by just one light source'.
The code where I'm adding the lighting effects is:
// trace lights
for ( int l=0; l<primitives.count; l++) {
Primitive* p = [primitives objectAtIndex:l];
if (p.light)
{
Sphere * lightSource = (Sphere *)p;
// calculate diffuse shading
Vector3 *light = [[Vector3 alloc] init];
light.x = lightSource.centre.x - intersectionPoint.x;
light.y = lightSource.centre.y - intersectionPoint.y;
light.z = lightSource.centre.z - intersectionPoint.z;
[light normalize];
Vector3 * normal = [[primitiveThatWasHit getNormalAt:intersectionPoint] retain];
if (primitiveThatWasHit.material.diffuse > 0)
{
float illumination = DOT(normal, light);
if (illumination > 0)
{
float diff = illumination * primitiveThatWasHit.material.diffuse;
// add diffuse component to ray color
colour.red += diff * primitiveThatWasHit.material.colour.red * lightSource.material.colour.red;
colour.blue += diff * primitiveThatWasHit.material.colour.blue * lightSource.material.colour.blue;
colour.green += diff * primitiveThatWasHit.material.colour.green * lightSource.material.colour.green;
}
}
[normal release];
[light release];
}
}
How can I make it look right?
It's a perceptual effect called Mach banding.
You are also very likely viewing the images in the wrong color space. Your ray tracer is doing the lighting math in a "linear" space, but then you are almost certainly viewing those images on a display with a nonlinear response, and therefore not even seeing the correct results. This could easily be making the Mach bands much more prominent than if you were displaying them properly. Try learning about gamma correction.
Your eyes are decieving you. If you move the spheres from the 3 pictures together you will very clearly see that the areas are the same color when single light and brighter when double lit. If you want to make it look nicer I suggest you add a whole arc of light sources between the current ones.
You've saturated one colour channel in the image; turn down the brightness a bit and see what happens.
Are you sure your lighting directions are both normalized?
May be worth it to throw an assert in there.