I've implemented Box2dWeb into a Node.js server and everything works fine apart from collisions. When there are 2 players connected their bodies don't collide - just go through each other. Here's the player body creation code:
//World creation
var world = new b2World(new b2Vec2(0, 0));
//Body+Fixture creation
var bodyDef = new b2BodyDef();
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.x = 100;
bodyDef.position.y = 100;
bodyDef.linearDamping = 5;
bodyDef.angularDamping = 1;
var fixDef = new b2FixtureDef();
fixDef.density = 0.001;
fixDef.friction = 1;
fixDef.restitution = 1;
fixDef.shape = new b2CircleShape;
fixDef.shape.SetRadius(8);
var body = world.CreateBody(bodyDef);
body.CreateFixture(fixDef);
Any help is very much appreciated!
EDIT: I've added this code:
var listener = new Box2D.Dynamics.b2ContactListener;
listener.BeginContact = function(contact) {
console.log(contact.GetFixtureA().GetBody().GetUserData());
}
world.SetContactListener(listener);
and once the bodies collide, I get "null" in the console.
OK, that was simple, just as I expected it would be. I changed the code from:
this.world.Step(deltaTime);
to
this.world.Step(deltaTime, 10, 10);
Related
So I am using this npm package: node-stl
And its working great. However the regexp syntax, mathematics and geometrical calculations are somewhat confusing to me. Especially all at the same time.
Basically what I want to achieve is to extend the script to calculate the bounding box of the STL.
Here is the main file that calculates the volume and weight of the STL being parsed/read.
var fs = require('fs');
// Vertex
function Vertex (v1,v2,v3) {
this.v1 = Number(v1);
this.v2 = Number(v2);
this.v3 = Number(v3);
}
// Vertex Holder
function VertexHolder (vertex1,vertex2,vertex3) {
this.vert1 = vertex1;
this.vert2 = vertex2;
this.vert3 = vertex3;
}
// transforming a Node.js Buffer into a V8 array buffer
function _toArrayBuffer (buffer) {
var
ab = new ArrayBuffer(buffer.length),
view = new Uint8Array(ab);
for (var i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return ab;
}
// calculation of the triangle volume
// source: http://stackoverflow.com/questions/6518404/how-do-i-calculate-the-volume-of-an-object-stored-in-stl-files
function _triangleVolume (vertexHolder) {
var
v321 = Number(vertexHolder.vert3.v1 * vertexHolder.vert2.v2 * vertexHolder.vert1.v3),
v231 = Number(vertexHolder.vert2.v1 * vertexHolder.vert3.v2 * vertexHolder.vert1.v3),
v312 = Number(vertexHolder.vert3.v1 * vertexHolder.vert1.v2 * vertexHolder.vert2.v3),
v132 = Number(vertexHolder.vert1.v1 * vertexHolder.vert3.v2 * vertexHolder.vert2.v3),
v213 = Number(vertexHolder.vert2.v1 * vertexHolder.vert1.v2 * vertexHolder.vert3.v3),
v123 = Number(vertexHolder.vert1.v1 * vertexHolder.vert2.v2 * vertexHolder.vert3.v3);
return Number(1.0/6.0)*(-v321 + v231 + v312 - v132 - v213 + v123);
}
// parsing an STL ASCII string
function _parseSTLString (stl) {
var totalVol = 0;
// yes, this is the regular expression, matching the vertexes
// it was kind of tricky but it is fast and does the job
var vertexes = stl.match(/facet\s+normal\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+outer\s+loop\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+endloop\s+endfacet/g);
vertexes.forEach(function (vert) {
var preVertexHolder = new VertexHolder();
vert.match(/vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s/g).forEach(function (vertex, i) {
var tempVertex = vertex.replace('vertex', '').match(/[-+]?[0-9]*\.?[0-9]+/g);
var preVertex = new Vertex(tempVertex[0],tempVertex[1],tempVertex[2]);
preVertexHolder['vert'+(i+1)] = preVertex;
});
var partVolume = _triangleVolume(preVertexHolder);
totalVol += Number(partVolume);
})
var volumeTotal = Math.abs(totalVol)/1000;
return {
volume: volumeTotal, // cubic cm
weight: volumeTotal * 1.04 // gm
}
}
// parsing an STL Binary File
// (borrowed some code from here: https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/STLLoader.js)
function _parseSTLBinary (buf) {
buf = _toArrayBuffer(buf);
var
headerLength = 80,
dataOffset = 84,
faceLength = 12*4 + 2,
le = true; // is little-endian
var
dvTriangleCount = new DataView(buf, headerLength, 4),
numTriangles = dvTriangleCount.getUint32(0, le),
totalVol = 0;
for (var i = 0; i < numTriangles; i++) {
var
dv = new DataView(buf, dataOffset + i*faceLength, faceLength),
normal = new Vertex(dv.getFloat32(0, le), dv.getFloat32(4, le), dv.getFloat32(8, le)),
vertHolder = new VertexHolder();
for(var v = 3; v < 12; v+=3) {
var vert = new Vertex(dv.getFloat32(v*4, le), dv.getFloat32((v+1)*4, le), dv.getFloat32( (v+2)*4, le ) );
vertHolder['vert'+(v/3)] = vert;
}
totalVol += _triangleVolume(vertHolder);
}
var volumeTotal = Math.abs(totalVol)/1000;
return {
volume: volumeTotal, // cubic cm
weight: volumeTotal * 1.04 // gm
}
}
// NodeStl
// =======
// > var stl = NodeStl(__dirname + '/myCool.stl');
// > console.log(stl.volume + 'cm^3');
// > console.log(stl.weight + 'gm');
function NodeStl (stlPath) {
var
buf = fs.readFileSync(stlPath),
isAscii = true;
for (var i=0, len=buf.length; i<len; i++) {
if (buf[i] > 127) { isAscii=false; break; }
}
if (isAscii)
return _parseSTLString(buf.toString());
else
return _parseSTLBinary(buf);
}
module.exports = NodeStl;
If anyone could help me with this it would be great. I know and it feels like it simple. That I just need to know max/min of the different directions(x,y,z) and could then calculate the bounding box.
But I do not understand what the max/min for x,y and z is here. Please answer if you have an idea.
I've made a new branch https://github.com/johannesboyne/node-stl/tree/boundingbox could you please verify whether the applied algorithm works?
Best,
Johannes
Edit: If the branch is stable -> works I'll push it into v.0.1.0 (don't know why it is still 0.0.1)
I've added a body that should have gravity to my game, so picture a big empty screen with a circle for "Earth" in the middle.
What methods would let me have any other body added to the game be "accelerated" or "attracted" to this circle? Basically if an asteroid appears, it should keep it's initial velocity, but be affected by Earth's gravity.
I believe that I found this method that you're looking for here.
I also have an example of that method in action here.
Here is the source code for my example:
// Global constants
var GAME_WIDTH = 800;
var GAME_HEIGHT = 600;
var SHIP_X_POS = 100;
var SHIP_Y_POS = 200;
var PLANET_X_POS = 400;
var PLANET_Y_POS = 300;
var ACCELERATION_TOWARDS_PLANET = 500;
var SHIP_VELOCITY_X = 150;
var SHIP_VELOCITY_Y = 150;
// Global variables
var ship;
var planet;
var game = new Phaser.Game(GAME_WIDTH, GAME_HEIGHT, Phaser.AUTO, "game", {preload: preload, create: create, update: update});
function preload () {
game.load.image("ship", "sprites/phaser_ship.png");
game.load.image("planet", "sprites/planet.png");
}
function create () {
var ship = game.add.sprite(SHIP_X_POS, SHIP_Y_POS, "ship");
game.physics.arcade.enable(ship);
ship.body.velocity.x = SHIP_VELOCITY_X;
ship.body.velocity.y = SHIP_VELOCITY_Y;
var planet = game.add.sprite(PLANET_X_POS, PLANET_Y_POS, "planet");
game.physics.arcade.enable(planet);
planet.body.immovable = true;
game.physics.arcade.accelerateToObject(ship, planet, ACCELERATION_TOWARDS_PLANET);
}
function update () {
// nothing to update
}
In node js, after running the for loop, descrip does not contain anything, no field written into the descrip array, why?
data = data['data'];
var course = data['course'];
data = data['sections'];
var descrip = new Array();
console.log(data.length);
for (var i = data.size - 1; i >= 0; i--) {
var data = data[i];
var section = data['section'];
var day = data['day'];
var date = data['date'];
var start = data['start_time'];
var end = data['end_time'];
var location = data['location'];
var res = 'Section: '+section+'\nDate: '+date+' '+day+'\nLocation: '+location+'\nStart: '+start+'\tEnd: '+end;
descrip.push(res);
};
Assuming you expect data to be an array, data.size - 1 will be -1 since data.size is null. So it will exit the loop immediately. You probably want data.length.
The length of an array in JavaScript is returned by the length property:
for (var i = data.length - 1; i >= 0; i--) {
// no block scope in JS, using data as a variable name here overwrites array
// var data = data[i];
var _data = data[i];
var section = _data['section'];
var day = _data['day'];
var date = _data['date'];
var start = _data['start_time'];
var end = _data['end_time'];
var location = _data['location'];
var res = 'Section: '+section+'\nDate: '+date+' '+day+'\nLocation: '+location+'\nStart: '+start+'\tEnd: '+end;
descrip.push(res);
};
Also, as pointed out in the comments by #Red Alert, you're overwriting your data variable in the for loop (JavaScript has no concept of block scope). I've renamed it _data, but you could probably come up with a more meaningful name to distinguish between the array and the element of the current iteration.
I need to offer a feature which allows InDesign users to select a page range in an InDesign document and create a new document out of those pages. This sounds simple, but it isn't...
I have tried many different ways of doing this but they have all failed to some degree. Some methods put all pages in a single spread (which sometimes makes InDesign crash). The best I've been able to do (see code below) still has problems at the beginning and the end (see screenshots below):
The original document:
The new document:
The question: How can I create a new document out of a subset of another document's pages (in InDesign using ExtendScript) without having the problems shown in the screenshots?
note: The behavior of the script is quite different in CS5.5 and CS6. My question concerns CS6.
The second screenshot was obtained by applying the following code to the document shown in the first screenshot:
CODE
var firstPageName = { editContents: "117" }; // This page number is actually entered by the user in an integerEditbox
var lastPageName = { editContents: "136" }; // This page number is actually entered by the user in an integerEditbox
var sourceDocument = app.activeDocument;
var destDocument = app.documents.add();
destDocument.importStyles(ImportFormat.paragraphStylesFormat, new File(sourceDocument.filePath + "/" + sourceDocument.name), GlobalClashResolutionStrategy.LOAD_ALL_WITH_OVERWRITE);
destDocument.importStyles(ImportFormat.characterStylesFormat, new File(sourceDocument.filePath + "/" + sourceDocument.name), GlobalClashResolutionStrategy.LOAD_ALL_WITH_OVERWRITE);
destDocument.viewPreferences.horizontalMeasurementUnits = sourceDocument.viewPreferences.horizontalMeasurementUnits;
destDocument.viewPreferences.verticalMeasurementUnits = sourceDocument.viewPreferences.verticalMeasurementUnits;
destDocument.documentPreferences.facingPages = sourceDocument.documentPreferences.facingPages;
destDocument.documentPreferences.pageHeight = sourceDocument.documentPreferences.pageHeight;
destDocument.documentPreferences.pageWidth = sourceDocument.documentPreferences.pageWidth;
destDocument.documentPreferences.pageSize = sourceDocument.documentPreferences.pageSize;
var sourceSpreads = sourceDocument.spreads;
var nbSourceSpreads = sourceSpreads.length;
var firstPageFound = false;
var lastPageFound = false;
var i;
var newSpreadNeeded;
var currentDestSpread;
for (i = 0; !lastPageFound, i < nbSourceSpreads; ++i) {
newSpreadNeeded = true;
var sourcePages = sourceSpreads[i].pages;
var nbSourcePages = sourcePages.length;
var j;
for (j = 0; !lastPageFound, j < nbSourcePages; ++j) {
if (sourcePages[j].name === firstPageName.editContents) {
firstPageFound = true;
destDocument.documentPreferences.startPageNumber = parseInt(firstPageName.editContents); // We want to preserve page numbers
}
if (firstPageFound) {
// Copy this page over to the new document.
var firstInNewSpread = false;
if (newSpreadNeeded) {
currentDestSpread = destDocument.spreads.add();
newSpreadNeeded = false;
firstInNewSpread = true;
}
var newPage = sourcePages[j].duplicate(LocationOptions.AT_END, currentDestSpread);
var k;
for (k = 0; k < newPage.index; ++k) {
currentDestSpread.pages[k].remove();
}
}
if (sourcePages[j].name === lastPageName.editContents) {
lastPageFound = true;
}
}
}
destDocument.spreads[0].remove();
I was hacking around and came up with this little script. Although it approaches the problem from the opposite direction, it seems to work fine here. Also, I'm still running in InDesign CS5, but maybe it will work for you. Hopefully I got the gist of your question?
This will extract pages 3 through 5 into a separate document:
var doc = app.activeDocument;
var newFilePath = doc.filePath + "/subset_" + doc.name;
var newFile = File(newFilePath); // Create a new file path
doc.saveACopy(newFile); // Save a copy of the doc
var newDoc = app.open(newFile); // Open the copy
var firstPageNum = 3; // First page number in the range
var lastPageNum = 5; // Last page number in the range
var firstPage = newDoc.pages[firstPageNum-1];
var lastPage = newDoc.pages[lastPageNum-1];
// Remove all text from the last page in the range to the end of the document
var lastPageFrames = lastPage.textFrames.everyItem().getElements();
for (var i=0; i < lastPageFrames.length; i++) {
var frame = lastPageFrames[i];
var parentStory = frame.parentStory;
var lastFrameInsert = frame.insertionPoints.lastItem();
var lastStoryInsert = parentStory.insertionPoints.lastItem();
var textAfter = parentStory.insertionPoints.itemByRange(lastFrameInsert,lastStoryInsert);
textAfter.remove();
};
// Remove all text from the beginning of the document to the first page in the range
var firstPageFrames = firstPage.textFrames.everyItem().getElements();
for (var i=0; i < firstPageFrames.length; i++) {
var frame = firstPageFrames[i];
var parentStory = frame.parentStory;
var firstFrameInsert = frame.insertionPoints.firstItem();
var textBefore = parentStory.insertionPoints.itemByRange(0,firstFrameInsert.index);
textBefore.remove();
};
// Remove the pages that aren't in the range
var allPages = newDoc.pages.everyItem().getElements();
for (var i=0; i < allPages.length; i++) {
var page = allPages[i];
if (i < firstPageNum || i > lastPageNum) {
page.remove();
}
};
Hi i have to create a json sting in javascript like this
{widget_list:[{widget_id:1,new_position:2},{widget_id:2,new_position:3}, . . .]}
using json.org library. Function i am using of this library is
var json_text =
JSON.stringify(uploaded, "", "");
Which creates a perfect json string i am able to generate when there is a no array
function uploaded()
{
}
var uploaded = new Uploaded();
uploaded.widget_id = 1;
uploaded.new_position = 2;
var json_text = JSON.stringify(uploaded, "", "");
when u alert json_text u will get {"widget_id":1,"new_position":2} requirment is just download a file json2.js from json.org for javascript and include it.
so please help some logic issue i am unable to create....
thanks in advance....
uploaded = {};
var a = [];
uploaded.widget_id = 1;
uploaded.new_position = 2;
a[0] = uploaded;
uploaded.widget_id = 2;
uploaded.new_position = 3;
a[1] = uploaded;
uploaded_new = {}
uploaded_new.widget_list = a
alert( JSON.stringify(uploaded_new, "", ""));
alert will give
{"widget_list":[{"widget_id":2,"new_position":3},{"widget_id":2,"new_position":3}]}
I came across this looking for a similar solution, in that it helped. But you need to re-initialize the "uploaded" object, otherwise it over-writes the existing values.
So, with that slight modification, it would be
uploaded = {};
var a = [];
uploaded.widget_id = 1;
uploaded.new_position = 2;
a[0] = uploaded;
**uploaded = {};**
uploaded.widget_id = 2;
uploaded.new_position = 3;
a[1] = uploaded;
uploaded_new = {}
uploaded_new.widget_list = a
alert( JSON.stringify(uploaded_new, "", ""));