OrbitControl.js with smoother zooming and rotating? - javascript

My demo is up here
You'll notice the zooming is quite choppy. The rotating is very static.
I'm looking to achieve similar results to Google's WebGL Globe.
At first I was using the standard OrbitControl.js file
but I wasn't liking the overall feel of it. So I started using this one which
includes some part about momentum and such.
I've tried embedding it but I had little luck.
// CONTROLS
cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement);
cameraControls.target.set(0, 0, 0);
cameraControls.maxDistance = 610;
cameraControls.minDistance = 210;
cameraControls.userRotateSpeed = 500;
cameraControls.momentumDampingFactor = 8;
cameraControls.momentumScalingFactor = 0.005;
cameraControls.getMouseProjectionOnBall2 = cameraControls.getMouseProjectionOnBall;
cameraControls.getMouseProjectionOnBall = function(x, y){ return cameraControls.getMouseProjectionOnBall2.call(cameraControls, x, cameraControls.screen.height/2);}
Playing around with the numbers on the momentum lines hasn't helped much.
Is there something I'm not doing right or is this just a limitation of the script?
Are there any other scripts out there with a smoother feel than OrbitConrol.js?
Note: Changing the user rotating speed parameter does nothing.
Note2: I am basically trying to build this
Notice how smooth the rotating is. I don't want to use trackballcontrol.js because it doesn't limit the rotating angle like orbitcontrol.js

Related

Algorithm for drawing a "Squiggly wiggly" pattern

I'm looking to have an algorithm that can randomly draw a "squiggly wiggly" pattern as per the picture.
It would be nice if it were progressively drawn as you would draw it with a pen and if it were based on speed, acceleration and forces like a double pendulum animation might be.
This would be for javascript in the p5 library.
Is there some way of producing this that a) looks hand drawn and b) fills a page, somewhat like a Hilbert curve?
Very interested to hear ideas of how this could be produced, regardless of whether there is some kind of formal algorithm, although a formal algorithm would be best.
Cheers
I can think of two solutions, but there could be more as I'm not very good at coding in general yet.
First of all, you can use perlin noise. With the code
var noiseSeeds = [];
//This changes the noise value over time
var noiseTime = 0;
var x = 0;
var y = 0;
function setup() {
createCanvas(400, 400);
//This will help for making two separate noise values later
noiseSeeds = [random(100), random(100)];
}
function draw() {
//Finding the x value
noiseSeed(noiseSeeds[0]);
x = noise(noiseTime)*400;
//Finding the y value
noiseSeed(noiseSeeds[1]);
y = noise(noiseTime)*400;
//Increasing the noise Time so the next value is slightly different
noiseTime += 0.01;
//Draw the point
stroke(0);
strokeWeight(10);
point(x, y);
}
You can create a scribble on screen. You would have to use createGraphics()in some way to make this more efficient. This method isn't the best because the values are generally closer to the center.
The second solution is to make a point that has two states - far away from an edge and close to an edge. While it is far away, the point would keep going in relatively the same direction with small velocity changes. However, the closer the point gets to the edges, the (exponentially) bigger the velocity changes so that the point curves away from the edge. I don't know exactly how you could implement this, but it could work.

Experiencing something odd when using THREE.Raycaster for collision detection (r68)

I've been using the THREE.Raycaster successfully to test collisions for many things in my game engine so far, it's great and it works well.
However, recently I've run into something quite peculiar which I cannot seem to figure out. From my point of view, my logic and code are sound but the expected result is not correct.
Perhaps I'm just missing something obvious so I thought I'd ask for some help.
I am casting rays out from the center of the top of a group of meshes, one by one, in a circular arc. The meshes are all children of a parent Object3D and the goal is to test collisions between the origin mesh and other meshes which are also children of the parent. To test my rays, I am using the THREE.ArrowHelper.
Here's an image of the result of my code - http://imgur.com/ipzYUsa
In this image, the ArrowHelper objects are positioned (origin:direction) exactly how I want them. But yeah, there's something wrong with this picture, the code that is produces this is:
var degree = Math.PI / 16,
tiles = this.tilesContainer.children,
tilesNum = tiles.length,
raycaster = new THREE.Raycaster(),
rayDirections, rayDirectionsNum, rayOrigin, rayDirection, collisions,
tile, i, j, k;
for (i = 0; i < tilesNum; i++) {
tile = tiles[i];
rayOrigin = new THREE.Vector3(
tile.position.x,
tile.geometry.boundingBox.max.y,
tile.position.z
);
rayDirections = [];
for (j = 0; j < Math.PI * 2; j += degree) {
rayDirections.push(new THREE.Vector3(Math.sin(j), 0, Math.cos(j)).normalize());
}
rayDirectionsNum = rayDirections.length;
for (k = 0; k < rayDirectionsNum; k++) {
rayDirection = rayDirections[k];
raycaster.set(rayOrigin, rayDirection);
collisions = raycaster.intersectObjects(tiles);
this.testRay(rayOrigin, rayDirection, collisions);
}
}
The testRay method looks like this:
testRay: function (origin, direction, collisions) {
var arrowHelper = new THREE.ArrowHelper(
direction,
origin,
1,
(collisions.length === 0) ? 0xFF0000 : 0x0000FF
);
this.scene.add(arrowHelper);
}
Now, obviously, something is off about this image. The rays that collide with other meshes should be blue, while those that do not collide should be red.
It's clear from this image that something is totally out of whack, and when I inspect the collisions, I get some really off results. For a lot of those rays which appear blue in the image, I'm getting a huge number of collisions, something like 30 collisions for a single ray sometimes, but nothing for the others even when they are right next to other tiles.
I just can't figure out what it might be. How can it be that so many rays that should be blue are red? And how can rays from tiles at the edge of the level have blue collisions to tiles that do not exist?
Really scratching my head (read: bashing my head repeatedly) over this one, any help would be super appreciated!
The solution was actually outside this code and not, at least I don't believe, related to the outdated r68 build.
When making the tile meshes, I needed to set three properties on them
tileMesh.matrixAutoUpdate = false;
tileMesh.updateMatrix();
tileMesh.updateMatrixWorld(); // this is new
I was doing the first two, just not the last one. Why this is necessary, I do not know, it seems a little odd to me but this is what fixed my problem. I had an AxisHelper in the scene, if you look at the original image, you'll notice that all the ArrowHelper objects that are blue are actually pointing towards the AxisHelper. This is really weird because the AxisHelper was added to the scene, not to tilesContainer. Adding the ArrowHelper objects to tilesContainer did not help.
The process to render the scene had the raycaster code run before the AxisHelper was added to the scene and before the initial render happened. The problem was also fixed if I moved the raycaster code call after the AxisHelper was added, but this was a hacky solution.
So the true fix was to add .updateMatrixWorld() to the tiles. The result now looks like this http://imgur.com/8LewqxL, which is correct (the ArrowHelper objects have been shortened in length so they don't overlap).
Big thanks to Manthrax for his help on this one.
I think you make some local vs global space error. I don't see so fast where exactly you go wrong, but all your position and direction calculations seem to be in the local system of the tilesContainer. Are you consistent in your local vs global coordinate system handling?
For example you add your arrowHelper to the scene instead of to the tilesContainer. It could be that the tilesContainer has some rotation set and because of this the arrows are pointing in another direction then you expected.
What happens for example if you add the arrows to the tilesContainer instead?

Image Flickering In Canvas Game

For a university project I have been tasked with creating a Flappy Bird clone. It's being done using the HTML5 canvas.
The issue doesn't happen very often, but it seems that every 6 or so seconds, the grass will flicker. I'm not sure what's causing this, it could be a performance issue.
Here is a link so you may see the issue: http://canvas.pixcelstudios.uk
Here is the function I'm using to the draw the grass:
var drawGrass = function(cWidth, ctx, minusX)
{
var x = bg_grass.x;
var y = bg_grass.y;
var w = bg_grass.w;
var h = bg_grass.h;
var img = bg_grass.img;
if (minusX[0] >= cWidth)
{
bg_grass.x = 0;
minusX[0] = 0;
}
ctx.drawImage(img, x, y, w, h);
if (minusX[0] > 0)
{
ctx.drawImage(img, w-minusX[0], y, w, h);
}
};
Basically, I'm drawing two grass sprites, each taking up a canvas width. One starts with an X of 0 and the other starts at the end of the canvas. Both are decremented each frame, then one is completely off the screen, it's completely reset to keep it looping.
I don't think it's anything to do with my update loop which is as follows:
this.update = function()
{
clearScreen();
updateBackground();
updatePositions();
checkCollisions();
render();
requestAnimFrame(gameSpace.update);
};
I've done a little bit of reading and I've read about having a second canvas to act as a buffer. Apparently this can stop flickering and improve performance? But all of the examples I've seen show the parts being drawn into the canvas out of a loop and I can't really see how doing it within a game loop (moving parts and all) would increase performance rather than decrease it. Surely the same operations are being performed, except now you also have to draw the second canvas onto the first?
Please let me know if you need any more information (although you should be able to see the whole source from the web link).
Thanks!
Okay I found the issue! Was just a simple mistake in my drawGrass function.
Due to the ordering, there'd be just a single frame where I'd set my shorthand X variable to bg_grass.x and THEN set bg_grass.x to something else, therefore drawing the wrong value.
I've now set my shorthand variables after the first if-statement.
However, if anyone could provide any insight into the second part of the question regarding a buffer canvas, I'd still much appreciate that.

Improving slow canvas animation on Retina iPad - KineticJS

I am using KineticJS to perform HTML Canvas animations. Animations work perfectly on all desktop browsers, and non retina iDevices (including iPad mini). However, from a retina device (browser or in-app webview using appcelerator) these animations are very sluggish. I have seen similar issues with canvas animations on retina display, but have not found any true solution.
My Stage constructor is 1024w x 768h.
All images are preloaded. And animations are constructed using the preloader's callback function.
If I reduce my stage size by half (and scale inner contents accordingly), the animation will play almost normally (still a little choppier than other ipads). My only justification for trying this was my very poor understanding that a retina display is two 'points'/pixel.
Any insight or ideas are welcome. My next attempt is to start changing image resolutions, rather than scaling dynamically.
This is due to a feature added four months ago. KineticJS will recognize if the pixelratio of the device is over 1 and try to make it as sharp as with pixelratio 1. The problem is, like you have found out, that it kills the performance to the point that it's useless. We have found this to be the case for our use cases.
Our solution: We commented out the pixel ratio part in KineticJS and hard coded it to always be one.
Pros:
The performance goes back up to normal
Cons:
Image is not as sharp
This is the part where we have made the change:
Kinetic.Canvas = function(width, height, pixelRatio) {
// eduplus change to fix pixel ratio performance problems
this.pixelRatio = 1; //pixelRatio || _pixelRatio;
When discussing this with Eric, he made comments to investigate pixel ratio performance, but I don't think he has had the time to do that yet. Hope this helps!
Using KineticJS 5 or above (I am not sure when exactly this global setting was introduced), the simplest and least intrusive way to do this is to set Kinetic.pixelRatio to your desired value before instantiating your stage:
Kinetic.pixelRatio = 1;
var stage = new Kinetic.Stage({
...
});
I use this before instantiating my Stage to overload pixelRatio without modifying KineticJS's source file. (Saves you from having to update the source file after any updates.)
https://gist.github.com/echong/6107722
CoffeeScript:
# Adjust device pixel ratio
for className in ["HitCanvas", "SceneCanvas", "Canvas"]
Kinetic[className].prototype.init = ((p_method) -> (p_config={}) ->
p_config.pixelRatio = 1
p_method.call #, p_config
) Kinetic[className].prototype.init
JavaScript:
_ref = ["HitCanvas", "SceneCanvas", "Canvas"];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
className = _ref[_i];
Kinetic[className].prototype.init = (function(p_method) {
return function(p_config) {
if (p_config == null) {
p_config = {};
}
p_config.pixelRatio = 1;
return p_method.call(this, p_config);
};
})(Kinetic[className].prototype.init);
}

Three.js Scene Violently Shaking

I am currently working on a project that involves working with very large and very small distances using three.js
I am having an issue on the smaller side of the scene, where the 'scene' will start violently shaking.
At first I assumed it was a problem with the Z-Buffer, so I have written a small snippet that changes the near and far properties of the camera every time a new area is entered. This helped with the issues of 'shimmering' I was having before, however the scene still moves dramatically at small distances.
One of the conditions under which this happens is as follows
camera.near = .0133333
camera.far = 12
positionToObjects = 6
this should mean that the z resolution is around : .0001, which I feel like should be good enough, but the shaking that occurs is MUCH more then this.
The Objects themselves range everywhere from -200000 - 200000 in the 'global' position, however the scenes themselves do not change position
The other thing that I was thinking that it could be is the camera controls I have been using which are (abbrviated) as follows
if(mouseIsDown == true){
if(this.movementSpeed < this.maxSpeed){
this.movementSpeed += this.acceleration
}else{
this.movementSpeed = this.maxSpeed
}
}else{
if(this.movementSpeed > this.minSpeed){
this.movementSpeed = this.movementSpeed/this.deceleration
}else{
this.movementSpeed = this.minSpeed
}
}
where this.minSpeed = 0, and this.movementSpeed is used to move the camera like so:
var actualSpeed = delta * this.movementSpeed;
this.object.translateZ( -actualSpeed * forwardOrAuto );
this.object.translateX( actualSpeed * sideSpeed );
this.object.translateY( actualSpeed * upSpeed );
However, even when the camera is not moving (up to 8 decimal places) the scene is still violently shaking
Are there any reasons that I cannot think of that would make a scene do this?
Please let me know if there is any more information that I can/should provide, and thank you in advance for your time.
May I suggest you use values for near and far which are not that small? (Specifically for near)
Near is used as the divider internally, so if you're using a small number (<1) you might lose precision and end with those violent movements, as the range of values you're moving around is way smaller than if you used larger near and far values.
That's why you'll find the default value for near is 0.1:
https://github.com/mrdoob/three.js/blob/r55/src/cameras/PerspectiveCamera.js#L13
... although I personally always use 1 for near.
Also, an online example is always good when asking for help in visual matters :-)

Categories

Resources