Entity not Visually Updating when its Position Changes - javascript

The title says it all, I can't get an entity to move around the globe visually, even though its position is moving. This code will reproduce the problem in Sandcastle:
var viewer = new Cesium.Viewer('cesiumContainer');
var e = viewer.entities.add({
name : 'Sphere',
position: Cesium.Cartesian3.fromDegrees(-100, 30.0, 300000.0),
ellipsoid : {
radii : new Cesium.Cartesian3(200000.0, 200000.0, 200000.0)
}
});
viewer.scene.postRender.addEventListener(function(scene, time) {
var pos = e.position._value;
var cart = Cesium.Ellipsoid.WGS84.cartesianToCartographic(pos);
pos = Cesium.Cartesian3.fromRadians(cart.longitude + (1 * Math.PI / 180), cart.latitude, cart.height);
e.position = pos;
});
If you select the sphere in the demo, you'll see that the green selection indicator will be moving around the globe, but the sphere will be stuck in one place. I imagine there's some simple function call I'm missing, but I've been googling for the last few hours and I can't find a solution.
I've already looked at the Picking demo on Sandcastle, but nothing there seems to be relevant. The functionality I'm looking for is just to have a shape looping through the same set of coordinates indefinitely, so I can't use a SampledPositionProperty, as far as I've seen anyway.

I suspect the cause of this is a little tricky: In Cesium, the ellipsoid geometry is build asynchronously by a Web Worker. By asking for a change in position with every postRender event, you're basically thrashing the worker, it can't get one request finished before the next one starts. So we end up never seeing the position update at all. If you relax the speed a bit, you'll notice the position does update.
For example, here's your code again with postRender replaced by setInterval of 400ms. This is more like a clock ticking than a smooth animation, but it shows the position being updated:
var viewer = new Cesium.Viewer('cesiumContainer');
var e = viewer.entities.add({
name : 'Sphere',
position: Cesium.Cartesian3.fromDegrees(-100, 30.0, 300000.0),
ellipsoid : {
radii : new Cesium.Cartesian3(200000.0, 200000.0, 200000.0)
}
});
window.setInterval(function() {
var pos = e.position._value;
var cart = Cesium.Ellipsoid.WGS84.cartesianToCartographic(pos);
pos = Cesium.Cartesian3.fromRadians(cart.longitude + (1 * Math.PI / 180), cart.latitude, cart.height);
e.position = pos;
}, 400);
Currently there's no way to know from the Entity API when the worker is done updating the geometry. You may have to move this example out of Entity API and use the Primitive API instead.

Related

Rotate wheel and stop at specific point in EaselJs

I am new to EaselJs.
I am rotating a wheel with 9x numbers and 3 (0x), the total of 12 numbers. I am able to rotate the wheel by calling function, but I want to stop it on predefined specific point/number of the wheel.
var _oContainer;
this._init = function(iXPos,iYPos){
_oWheel = s_oSpriteLibrary.getSprite("wheel_circle");
_oContainer = new createjs.Container;
_oContainer.x = CANVAS_WIDTH - 200;
_oContainer.y = CANVAS_HEIGHT - 350;
s_oStage.addChild(_oContainer);
img = createBitmap(_oWheel);
img.regX = _oWheel.width / 2;
img.regY = _oWheel.height / 2;
_oContainer.addChild(img);
}
this.spin = function(b, a){
//var h = new createjs.Bitmap(s_oSpriteLibrary.getSprite('wheel_circle'));
createjs.Tween.get(_oContainer).to({
rotation: _oContainer.rotation + a
}, 2600, createjs.Ease.quartOut).call(function() {
_oContainer.rotation %= 360;
})
}
I am calling the spin function as this.spin(5, 1131.7511808994204); on every time button is clicked.
Right now it is spinning and stopping randomly on every button click. How can stop it on a specific number/position on the wheel?
What value should I give in rotation:?
There are a lot of factors in play to do something like this. I made a quick demo to show how I would do it:
Draw the wheel (at center) with segments. It is important to know how many segments you have so you can choose a place to "end"
Start spinning. Just increment the rotation each tick depending on how fast you want it to go.
When "stopping", you have to do math to determine where to land
To get a realistic "slow down", make sure the remaining rotation in the tween is enough so it doesn't speed up or slow down too rapidly
Here is the fiddle: https://jsfiddle.net/lannymcnie/ych1qt8u/1/
// Choose an end number. In this case, its just a number between 0 and the number of segments.
var num = Math.random() * segments | 0,
// How many degrees is one segment?
// In my demo I use radians for `angle`, so I have to convert to degrees
angleR = angle * 180/Math.PI,
// Take the current rotation, add 360 to it to take it a bit further
// Note that my demo rotates backwards, so I subtract instead of add.
adjusted = c.rotation - 360,
// Determine how many rotations the wheel has already gone since it might spin for a while
// Then add the new angle to it (num*angleR)
// Then add a half-segment to center it.
numRotations = Math.ceil(adjusted/360)*360 - num*angleR - angleR/2;
Then I just run a tween to the new position. You can play with the duration and ease to get something you like.
createjs.Tween.get(c)
.to({rotation:numRotations}, 3000, createjs.Ease.cubicOut);
Technically, I should change the duration depending on the actual remaining spin, since depending on the result, it might not be super smooth. This came close enough, so I left it as-is.
Hope that helps! Let me know if I can clarify anything further.

Javascript sprites moving between two points

I'm wanting to get some sprites moving between two points in my (very basic) javascript game. Each sprite is randomly placed in the level, so I want them to move back and forth between their base position. I have the code below
function Taniwha(pos) {
this.basePos = this.pos;
this.size = new Vector(0.6, 1);
this.move = basePos + moveDist(5,0));
}
Taniwha.prototype.type = "taniwha"
var moveSpeed = 4;
Taniwha.prototype.act = function(step) {
this.move = ???
and this is where I get stuck. I'm not sure how to tell it to go left, back to base pos, right then back to base pos again (I plan to loop this). Does anyone have any advice? (also using Eloquen Javascript's example game as an outline/guide for this, if how I'm doing things seems odd!)
For horizontal movement, change x coordinate of the position.
var pos = { x: 1, y: 2 };
pos.x++ ; // This will move right
pos.x-- ; // This will move left
Likewise for vertical movement. You also need to update the coordinates after change for the object which you are drawing.
In truth ,there are lots of library to develop a game.
Use those, control a sprite is very easy.
Like:
Pixijs
CreateJS
Both of them are opensource project, you can watch and learn the source.
And have lots of examples and document.

Unfreeze bodies in Box2Djs or prevent from exiting world

I am working on a server side physics experiment where the user controls an object through a socket. The problem I am running into results when the user moves the object outside the boundaries of the world.
I am using Box2Djs as installed through npm.
I create world 500x500 and then attach the following listener to it:
var boundaryListener = new b2d.b2BoundaryListener();
boundaryListener.Violation = function (body) {
//we will move this body to the opposite side
var position = body.GetWorldCenter();
//snap to opposite side
if (position.x < 0) {
position.x = worldAABB.upperBound.x + position.x;
}
if (position.y < 0) {
position.y = worldAABB.upperBound.y + position.y;
}
if (position.x > worldAABB.upperBound.x) {
position.x -= worldAABB.upperBound.x;
}
if (position.y > worldAABB.upperBound.y) {
position.y -= worldAABB.upperBound.y;
}
body.m_flags = body.m_flags & (~b2d.b2Body.e_frozenFlag); //does nothing :(
}
this.world.SetBoundaryListener(boundaryListener);
worldAABB is the b2AABB that the world uses as a boundary.
The problem is that I have noticed that when the boundary listener is fired, the flags are set to 22 which is allowSleep, frozen, and island flags. It would seem that when a b2Body passes outside the world boundary, it is frozen. That last line is an attempt to unfreeze the body by messing with the internal flags, but I have a distinct feeling that's the wrong way to do it.
How can I unfreeze the body? There are no functions that clear the frozen flags that I can see (the javascript is over 10,000 lines long so I honestly haven't read the whole thing) and placing some bodies as walls seems to have no effect (the user's object passes right through them).
My walls are created like so:
//create walls
var wallShape = new b2d.b2PolygonDef();
wallShape.SetAsBox(500, 10);
wallShape.density = 0.0;
wallShape.friction = 0.3;
var bodyDef = new b2d.b2BodyDef();
bodyDef.position.Set(250, 20);
var north = this.world.CreateBody(bodyDef);
north.CreateShape(wallShape);
bodyDef = new b2d.b2BodyDef();
bodyDef.position.Set(250, 499);
var south = this.world.CreateBody(bodyDef);
south.CreateShape(wallShape);
bodyDef = new b2d.b2BodyDef();
bodyDef.position.Set(499,250);
bodyDef.angle = Math.PI / 2;
var east = this.world.CreateBody(bodyDef);
east.CreateShape(wallShape);
bodyDef = new b2d.b2BodyDef();
bodyDef.position.Set(1, 250);
bodyDef.angle = Math.PI / 2;
var west = this.world.CreateBody(bodyDef);
west.CreateShape(wallShape);
Does anyone have any insights on how to fix this? There is very very little documentation I can find on using Box2D in javascript aside from the flash documentation that the website points to (which doesn't match half the time) and the C++ documentation which doesn't even talk about freezing.
It would probably be helpful to mention that the world has no gravity and all the objects have some linear and angular damping (its supposed to be a psuedo-in-space feel).
I had investigated Box2Djs source, and found next thing. Every time step Box2Djs checks if the body is inside the world boundaries. If body is out of range, then it "frozing", i.e. its excluding from collision detection. There this code (Body.js line 414):
Freeze: function(){
this.m_flags |= b2Body.e_frozenFlag;
this.m_linearVelocity.SetZero();
this.m_angularVelocity = 0.0;
for (var s = this.m_shapeList; s != null; s = s.m_next)
{
s.DestroyProxy();
}
}
Pay attention, this check performs every time step (b2Island.js 244). So, if you set e_frozenFlag at boundary listener, it will do nothing: flag will be set up at next time step. Thats more, after body had frozen, it losses its veolcity and its shapes looses theirs proxies in broad phase (as you can see from code above). Looks like proxies are not restroing automaticly, so, reseting flag is not enough.
I also not found somewhere in Box2Djs interface or logic for unfreezing bodies. Doing this manually is some kind of dirty trick, because you should acces BroadPhase, which is Box2Djs internal. Thats more, it dont help you, because on freezing body losses its velociy. But, as I see, you need continue body moving.
Solution is next. You should prevent body frozing at all in order to keep body in simulation after it moved out of world boundaries. It may be done by next trick. First, set world boundary with some large value. Then, set contact listener, and when body touches the walls, perform your boundary violation logic.
How to set contact listener in C++ you can see there: https://www.iforce2d.net/b2dtut/collision-callbacks Sory, I dont know java script and can't say, how to do this in Box2Djs.

Three.js particles to form a shape

I've been following this tutorial (http://creativejs.com/tutorials/three-js-part-1-make-a-star-field/) and everything is going fine, but I'd like to know how I can modify the script so then there's some form of callback when the particle reaches the end. I've modified the code in the tutorial so it's reversed the way the particles are moving.
What I'm wanting to try and create is a load of particles coming together to form a square, is it possible from using the code in the tutorial as a start and build on top of that or should I look elsewhere and start over?
Thanks in advance.
Wouldn't it be easy if you create the same amount of particles as the model's amount of vertices, and move the particles towards the vertices' position?
var p = emitter.geometry.vertices; // the vertices (particles) of your particle emitter
var m = model.geometry.vertices; // the vertices of the target model
for(var i in p) {
p[i].x = (p[i].x + m[i].x) / 2;
p[i].y = (p[i].y + m[i].y) / 2;
p[i].z = (p[i].z + m[i].z) / 2;
}

How can I make Raphael.js elements "wiggle" on the canvas?

I'm working on a project that uses SVG with Raphael.js. One component is a group of circles, each of which "wiggles" around randomly - that is, slowly moves along the x and y axes a small amount, and in random directions. Think of it like putting a marble on your palm and shaking your palm around slowly.
Is anyone aware of a Raphael.js plugin or code example that already accomplishes something like this? I'm not terribly particular about the effect - it just needs to be subtle/smooth and continuous.
If I need to create something on my own, do you have any suggestions for how I might go about it? My initial idea is along these lines:
Draw a circle on the canvas.
Start a loop that:
Randomly finds x and y coordinates within some circular boundary anchored on the circle's center point.
Animates the circle from its current location to those coordinates over a random time interval, using in/out easing to smooth the effect.
My concern is that this might look too mechanical - i.e., I assume it will look more like the circle is tracing a star pattern, or having a a seizure, or something like that. Ideally it would curve smoothly through the random points that it generates, but that seems far more complex.
If you can recommend any other code (preferably JavaScript) that I could adapt, that would be great too - e.g., a jQuery plugin or the like. I found one named jquery-wiggle, but that seems to only work along one axis.
Thanks in advance for any advice!
Something like the following could do it:
var paper = Raphael('canvas', 300, 300);
var circle_count = 40;
var wbound = 10; // how far an element can wiggle.
var circleholder = paper.set();
function rdm(from, to){
return Math.floor(Math.random() * (to - from + 1) + from);
}
// add a wiggle method to elements
Raphael.el.wiggle = function() {
var newcx = this.attrs.origCx + rdm(-wbound, wbound);
var newcy = this.attrs.origCy + rdm(-wbound, wbound);
this.animate({cx: newcx, cy: newcy}, 500, '<');
}
// draw our circles
// hackish: setting circle.attrs.origCx
for (var i=0;i<circle_count;i++) {
var cx = rdm(0, 280);
var cy = rdm(0, 280);
var rad = rdm(0, 15);
var circle = paper.circle(cx, cy, rad);
circle.attrs.origCx = cx;
circle.attrs.origCy = cy;
circleholder.push(circle);
}
// loop over all circles and wiggle
function wiggleall() {
for (var i=0;i<circleholder.length;i++) {
circleholder[i].wiggle();
}
}
// call wiggleAll every second
setInterval(function() {wiggleall()}, 1000);
http://jsfiddle.net/UDWW6/1/
Changing the easing, and delays between certain things happening should at least help in making things look a little more natural. Hope that helps.
You can accomplish a similar effect by extending Raphael's default easing formulas:
Raphael.easing_formulas["wiggle"] = function(n) { return Math.random() * 5 };
[shape].animate({transform:"T1,1"}, 500, "wiggle", function(e) {
this.transform("T0,0");
});
Easing functions take a ratio of time elapsed to total time and manipulate it. The returned value is applied to the properties being animated.
This easing function ignores n and returns a random value. You can create any wiggle you like by playing with the return formula.
A callback function is necessary if you want the shape to end up back where it began, since applying a transformation that does not move the shape does not produce an animation. You'll probably have to alter the transformation values.
Hope this is useful!
There is a very good set of easing effects available in Raphael.
Here's a random set of circles that are "given" bounce easing.
Dynamically add animation to objects
The full range of easing effects can be found here. You can play around with them and reference the latest documentation at the same time.
Putting calls in a loop is not the thing to do, though. Use callbacks, which are readily available.

Categories