Three.js save modified mesh vertices r67 - javascript

I have created a plane and when I click on a vertex, the vertex will move and render as expected . My problem is saving the mesh to a text file.The vertices don't seem to update on the file as expected.
If I move a vertex before the second render the vertex position will reflect on the external text file.
My question is once I have moved around a bunch of vertices x,y,z positions how do I save the result that appears on my screen as it seems to only save the original mesh .
var guiControls = new function () {
var t = ['Test Save File'];
this.save_mesh = function () {
for (var i = 0, j = ground.geometry.vertices.length; i < j; i++) {
t.push('['+ ground.geometry.vertices[i].x+','+ ground.geometry.vertices[i].y+ ','+ objects[0].geometry.vertices[i].z+ '#:'+']');
}
function passMesh(){
var data = {
value: t
};
$.post("./php/savefile.php", data);
}
passMesh();
};
I have tried to use the updates available:
geo.dynamic = true;
geo.computeVertexNormals();
geo.computeFaceNormals();
geo.verticesNeedUpdate = true;
geo.normalsNeedUpdate = true;
Any help is appreciated.

In 3D graphics all changes are only matrix transformations of the original mesh, which do not actually change this mesh. So my guess is that you need to apply the transformations to you objects prior to the export. try: .applyMatrix

Related

Drawing a line between moving objects

I'm trying to draw a line between two moving vertices. The vertex's drawing is stored in a variable called object, which has a position, which is a THREE.Vector3.
The line is created thusly:
var Line = function(scene, source, target){
var geometry = new THREE.Geometry();
geometry.dynamic = true;
geometry.vertices.push(source.object.position);
geometry.vertices.push(target.object.position);
geometry.verticesNeedUpdate = true;
var material = new THREE.LineBasicMaterial({ color: 0x000000 });
var line = new THREE.Line( geometry, material );
scene.add(line);
return line;
};
..., where source and target are vertices and the vertices get updated via:
vertex.object.position.add(vertex.velocity);
Now, I assigned the source.object.position and target.object.position to the line.geometry.vertices[0] and line.geometry.vertices[1] because I wanted one to update with the other. But instead, the vertex positions vary wildly from the line positions. The vertices are where they are, but the lines don't connect to the vertices.
How can I make the lines move with the vertices?
In your animation loop you have to set line.geometry.verticesNeedUpdate = true. Because every time after rendering it becomes false. jsfiddle example

Cesium - using camera to scale a polygon to match Lat-Lon positions while zoom-in/zoom-out

I am struggling with camera functionality that (I think) would provide a way to force my polygon to stick to the top of my house on zoom-out, zoom-in, and rotation (or camera move).
This question follows an earlier question that was resolved. Now I need a little help resolving my next issue.
The sample code I am trying to follow is located in the gold standard that appears to be baked into the existing camera controller here.
pickGlobe is executed with the parameters of the viewer, the correct mousePosition in world coordinates and a result parameter, which I don't care about right now. scene.pickPosition takes the c2position (Cartesian2) and should return the scratchDepthIntersection (Cartesian3). Instead, the returned value is undefined.
Here is my code:
function clickAction(click) {
var cartesian = scene.camera.pickEllipsoid(click.position, ellipsoid);
if (cartesian) {
var setCartographic = ellipsoid.cartesianToCartographic(cartesian);
collection.latlonalt.push(
Cesium.Math.toDegrees(setCartographic.latitude).toFixed(15),
Cesium.Math.toDegrees(setCartographic.longitude).toFixed(15),
Cesium.Math.toDegrees(setCartographic.height).toFixed(15)
);
lla.push(Cesium.Math.toDegrees(setCartographic.longitude), Cesium.Math.toDegrees(setCartographic.latitude));
if (lla.length >= 4) {
console.log((lla.length / 2) + ' Points Added');
}
enableDoubleClick();
enableDraw();
testMe(click.position); <--------------------- straight from the mouse click
}
}
var pickedPosition;
var scratchZoomPickRay = new Cesium.Ray();
var scratchPickCartesian = new Cesium.Cartesian3();
function testMe(c2MousePosition) { <--------------------- straight from the mouse click
if (Cesium.defined(scene.globe)) {
if(scene.mode !== Cesium.SceneMode.SCENE2D) {
pickedPosition = pickGlobe(viewer, c2MousePosition, scratchPickCartesian);
} else {
pickedPosition = camera.getPickRay(c2MousePosition, scratchZoomPickRay).origin;
}
}
}
var pickGlobeScratchRay = new Cesium.Ray();
var scratchRayIntersection = new Cesium.Cartesian3();
var c2position = new Cesium.Cartesian2();
function pickGlobe(viewer, c2MousePosition, result) { <--------------------- straight from the mouse click
c2position = c2MousePosition; <--------------------- setting to Cartesian2
var scratchDepthIntersection = new Cesium.Cartesian3();
if (scene.pickPositionSupported) {
scratchDepthIntersection = scene.pickPosition(c2MousePosition); <--------------------- neither works!
}
}
Here are my variables:
Here is the result:
Here are my questions to get this code working:
1. Why is scratchDepthIntersection not getting set? c2position is a Cartesian2 and c2MousePosition is straight from the mouse.click.position and scratchDepthIntersection is a new Cartesian3.
The correct value for mousePosition is a Cartesian2 containing window coordinates, not a Cartesian3. Such mouse coordinates usually come from a callback from Cesium.ScreenSpaceEventHandler, but can also be constructed from native JavaScript mouse/touch events.
If you inspect the contents of mousePosition, you should find x and y values in window pixel coordinates.
I see you edited the question to include the contents of mousePosition, and it looks like the mouse coordinates have already been converted into ellipsoid Cartesian3 coordinates, which will prevent this code from working. You want original mouse coordinates going directly into scene.pickPosition for this to work.

Three.js Event Listener in scene renderer

This will be a "strange" question, because my code works. I just want to check if it can be tweaked because I dont have programming experience.
I wrote a script that gets a stream of kinect joints and plots them on a three js scene on an coordinates system with a webgl renderer.
At first I create a set of spheres, based on Stemkoski's examples and then add the event listener for the json skeleton that arrives in the update function, so I can update the spheres coordinates and have it moving.
The only problem that this creates is that now I cannot rotate the coordinates system with my mouse (while I could when I was testing it with static spheres or with pulsing spheres, as in Stemkoski's example).
So the first question is how can I correct this problem.
The second, more complex question is this : Is this a correct practice? I may not be a developer but I have learned that when my gut says this is awkward or bad practice, it probably is.. Any help and suggestions, appreciated.
Oh, and I have implemented this for only one skeleton in the scene. I will try to make it for more skeletons but I ll wait for your input here in case this all could be simpler and better written.
Here's the relevant code, the initialization of the sphere/joints and the update function:
WholeSkeleton = new THREE.Object3D();
particleAttributes = { startSize: [], startPosition: [] };
var totalParticles = 20; //=num.skeleton.joints //add later variable number
var radiusRange = 50;
for (var i = 0; i < totalParticles; i++) { // INITIALIZE THE SKELETON JOINTS POSITION
var sphereMaterial = new THREE.MeshLambertMaterial({ color: 'rgb(255,0,0)' });
var jointSphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
//initialize positions
jointSphere.position.set(0, 0, 0);
WholeSkeleton.add(jointSphere);
// add variable qualities to arrays, if they need to be accessed later
particleAttributes.startPosition.push(jointSphere.position.clone());
}
scene.add(WholeSkeleton);
}
function animate() {
requestAnimationFrame(animate);
render();
update();
}
function update() {
document.addEventListener("skeletonEvent", function (e) {
jsonObject = e.detail.SkeletonSourceData;
// for (var i = 0; i < jsonObject.Skeletons.length; i++) {
for (var j = 0; j < jsonObject.Skeletons[0].Joints.length; j++) { //only for skeleton 0.
var incoming=jsonObject.Skeletons[0].Joints[j];
var joint = WholeSkeleton.children[j];
joint.position.x = (particleAttributes.startPosition[j].x + incoming.Position.X)*30;
joint.position.y = (particleAttributes.startPosition[j].y + incoming.Position.Y)*30;
joint.position.z = (particleAttributes.startPosition[j].z + incoming.Position.Z)*10;
}
// }
});
}
--

how I can erase from memory the scene and meshes? Three.js

I am adding "n" number of circles on the scene.
var radius = 1;
var segments = 32;
var circleGeometry = new THREE.CircleGeometry( radius, segments);
function generateCircles(){
//scene.remove(circle);
var count=0;
while (1000> count) {
circle = new THREE.Mesh (circleGeometry, material);
scene.add (circle);
count ++;
}
}
It is effective to do it this way ?.
in my code I call this function. and every time you call it, it all goes back slower, I guess it's because there are more objects in the scene. what can I do?
Each time the function is called I need erased completely from the memory stage and the circles that were generated.
with "slower", I mean that I want my application to run faster. every time I run the function add more and more circles. so I want to be removed earlier. to add new ones. if there are many circles in the scene it slows execution.
http://jsfiddle.net/v8oxsxtc/
You can remove the old circles from the scene by calling the scene.remove method on each of the circles you previously added. Here is a simple example using your code:
var lastCircles = null;
function generateCircles(){
var count=0;
if(lastCircles) { // remove old circles if they exist
lastCircles.forEach(function(c) {
scene.remove(c);
});
}
lastCircles = []; // clear cache
while (1000 > count) {
circle = new THREE.Mesh (circleGeometry, material);
lastCircles.push(circle); // add each circle to cache
scene.add (circle);
circle.position.set(count,count,count)
count ++;
}
}

event data in pixi.js

I just started playing around with pixi and have drawn multiple rectangles from an array with pixel coordinates like this:
var rectangle = [....];
....
var stage = new PIXI.Stage();
var renderer = PIXI.autoDetectRenderer(wrapper.getWidth(), wrapper.getHeight(), { transparent: true });
....
var graphics = new PIXI.Graphics();
graphics.interactive = true;
graphics.on("mouseover", function(e) {
this.alpha = 0.5;
}).on("mouseout", function() {
this.alpha = 1;
});
graphics.beginFill(0xFFFFFF);
graphics.lineStyle(2, 0x000000);
for (var i = 0; i < rectangle.length; i++) {
graphics.drawRect(rectangle[i][0], rectangle[i][1], 10, 10);
}
graphics.endFill();
stage.addChild(graphics);
renderer.render(stage);
The events are triggered but the object I get by "e" or "this" inside the callback is the object for all graphics. I want to get that single "mouseovered" rectangles object I can see in the graphicsData, but there is no id or anything to identify it by. How can I do this?
Performance is of essence as I'm going to render 20k+ rectangles or circles.
Without drawing each rectangle onto it's own PIXI.Graphics object you won't be able to get individual mouseover events. This is because as far as PIXI is concerned the Graphics object is a single bitmap image.
I would suggest performing your own hit tests inside the mouseover function to detect which rectangle the cursor is over.
If you are using PIXI.Rectangles you can take advantage of the built in Rectangle.Contains function to check if a point (in this case the mouse position) is inside the bounds.

Categories