@@ -396,6 +396,6 @@ #include "iesorBody.h" | ||
| Json::Value* maxCGL; | ||
| printf(" Conn chains: %i \n", connectionChains.size()); | ||
| // printf(" Conn chains: %i \n", connectionChains.size()); | ||
| for(int i=0; i < connectionChains.size(); i++) | ||
| { | ||
| printf(" Conn chain %i size: %i \n", i, connectionChains[i].size()); | ||
| // printf(" Conn chain %i size: %i \n", i, connectionChains[i].size()); | ||
@@ -425,3 +425,3 @@ if(connectionChains[i].size() == maxChain) | ||
| printf("Conn final: %i \n", connections.size()); | ||
| // printf("Conn final: %i \n", connections.size()); | ||
@@ -527,2 +527,5 @@ //make sure points are distinct, and no dupes -- we only need to do this once | ||
| // printf("Starting new genome\n\n\n"); | ||
| //Dictionary<string, List<PointF>> pointsChecked = new Dictionary<string, List<PointF>>(); | ||
@@ -543,2 +546,4 @@ //List<PointF> pList; | ||
| { | ||
| double* outs = queryCPPNOutputs(xyPoint.x, xyPoint.y, otherPoint.x, otherPoint.y, maxXDistanceCenter(xyPoint, otherPoint), minYDistanceGround(xyPoint, otherPoint)); | ||
@@ -575,3 +580,16 @@ double weight = outs[0]; | ||
| { | ||
| // bool xDif = (abs(xyPoint.x - otherPoint.x) > 0); | ||
| // bool yDif = (abs(xyPoint.y - otherPoint.y) > 0); | ||
| // printf("Successfull conn (%s, %s) - from %s, to: %s\n", | ||
| // (xDif ? "XDIF" : " "), | ||
| // (yDif ? "YDIF" : " "), | ||
| // xyPoint.toString().c_str(), | ||
| // otherPoint.toString().c_str()); | ||
| // printf("Successfull conn- from %s, to: %s\n", xyPoint.toString().c_str(), otherPoint.toString().c_str()); | ||
| //made it to connection, save our outputs | ||
@@ -578,0 +596,0 @@ Json::Value cppnOutputs(Json::arrayValue); |
@@ -76,7 +76,7 @@ #include "network.h" | ||
| return Sine; | ||
| else if(activationType == "input") | ||
| else if(activationType == "Linear") | ||
| return Linear; | ||
| else | ||
| { | ||
| printf("No known activation type!"); | ||
| { | ||
| printf("No known activation type sent to network. Choose from [BipolarSigmoid, Gaussian, Sine, Linear] -- not : %s\n", activationType.c_str()); | ||
| throw 1; | ||
@@ -125,3 +125,3 @@ } | ||
| { | ||
| printf("In order: %d \n", nodeOrderJSON[nIx].asInt()); | ||
| // printf("In order: %d \n", nodeOrderJSON[nIx].asInt()); | ||
| nodeOrder[nIx] = nodeOrderJSON[nIx].asInt(); | ||
@@ -135,3 +135,3 @@ } | ||
| { | ||
| printf("Weight: %f \n", weightsJSON[nIx].asDouble()); | ||
| // printf("Weight: %f \n", weightsJSON[nIx].asDouble()); | ||
| weights[nIx] = weightsJSON[nIx].asDouble(); | ||
@@ -161,3 +161,3 @@ } | ||
| { | ||
| printf("Register sampling: %d \n", registerList[nIx].asInt()); | ||
| // printf("Register sampling: %d \n", registerList[nIx].asInt()); | ||
| registerArrays[i][nIx] = registerList[nIx].asInt(); | ||
@@ -169,3 +169,3 @@ } | ||
| { | ||
| printf("Weight index: %d \n", weightList[nIx].asInt()); | ||
| // printf("Weight index: %d \n", weightList[nIx].asInt()); | ||
| weightArrays[i][nIx] = weightList[nIx].asInt(); | ||
@@ -172,0 +172,0 @@ } |
@@ -40,2 +40,8 @@ #define _USE_MATH_DEFINES | ||
| } | ||
| string dubString(double number) | ||
| { | ||
| ostringstream convert; // stream used for the conversion | ||
| convert << number; // insert the textual representation of 'number' in the characters in the stream | ||
| return convert.str(); | ||
| } | ||
@@ -240,4 +246,3 @@ #define SIZE 1024 | ||
| IESoRWorld::IESoRWorld() | ||
| void IESoRWorld::initializeWorld() | ||
| { | ||
@@ -253,11 +258,22 @@ this->interpolation =0; | ||
| //keep a list of shape and body identifiers | ||
| this->bodyList.clear(); | ||
| this->shapeList.clear(); | ||
| //this->bodyList = new vector<PhysicsID*>(); | ||
| //this->shapeList = new vector<PhysicsID*>(); | ||
| //this->bodyList = new Json::Value(Json::arrayValue); | ||
| //this->shapeList = new Json::Value(Json::arrayValue); | ||
| //keep a reference to loaded bodies | ||
| this->loadedBodyMap.clear(); | ||
| //keep a reference to every body according to ID | ||
| this->bodyMap.clear(); | ||
| //keep track of all the joints inside the system | ||
| this->boneList.clear(); | ||
| //we need to keep track of all our muscles too | ||
| this->muscleList.clear(); | ||
| //set default size | ||
| currentSize = b2Vec2(200, 150); | ||
| // Define the gravity vector. | ||
@@ -278,7 +294,4 @@ b2Vec2 gravity(0.0f, -15.0f); | ||
| // The body is also added to the world. | ||
| b2Body* groundBody = this->addBodyToWorld("ground", &groundBodyDef);//this->world->CreateBody(&groundBodyDef); | ||
| b2Body* groundBody = this->addBodyToWorld("ground", &groundBodyDef); | ||
| //b2Body* groundBody = this->world->CreateBody(&groundBodyDef); | ||
| // Define the ground box shape. | ||
@@ -292,68 +305,161 @@ b2PolygonShape groundBox; | ||
| this->addShapeToBody(groundBody, &groundBox, 0.0f); | ||
| //groundBody->CreateFixture(&groundBox, 0.0f); | ||
| } | ||
| // b2Vec2 canvas(200, 150); | ||
| //this->loadBodyIntoWorld(inBody, canvas); | ||
| void IESoRWorld::clearWorld() | ||
| { | ||
| //get rid of all our joints | ||
| //we now need to process all of our joints as well | ||
| b2Joint * J = this->world->GetJointList(); | ||
| //no joints for you! | ||
| while(J != NULL) | ||
| { | ||
| J->SetUserData(NULL); | ||
| // Define the dynamic body. We set its position and call the body factory. | ||
| b2BodyDef bodyDef; | ||
| bodyDef.type = b2_dynamicBody; | ||
| bodyDef.position.Set(0.0f, 24.0f); | ||
| //destroy destroy destroy!!! | ||
| this->world->DestroyJoint(J); | ||
| //add body to world using definition | ||
| // b2Body* body = this->addBodyToWorld("rect1", &bodyDef); | ||
| //loop to the next object | ||
| J = J->GetNext(); | ||
| } | ||
| // Define another box shape for our dynamic body. | ||
| b2PolygonShape dynamicBox; | ||
| dynamicBox.SetAsBox(5.0f, 5.0f); | ||
| //i want to see it all burn -- now the bodies | ||
| b2Body* B = this->world->GetBodyList(); | ||
| // Define the dynamic body fixture. | ||
| b2FixtureDef fixtureDef; | ||
| fixtureDef.shape = &dynamicBox; | ||
| fixtureDef.restitution = .5; | ||
| //this is so diabolical | ||
| while(B != NULL) | ||
| { | ||
| B->SetUserData(NULL); | ||
| // Set the box density to be non-zero, so it will be dynamic. | ||
| fixtureDef.density = 1.0f; | ||
| //destroy destroy destroy!!! | ||
| this->world->DestroyBody(B); | ||
| // Override the default friction. | ||
| fixtureDef.friction = 0.3f; | ||
| //loop to the next object | ||
| B = B->GetNext(); | ||
| // Add the shape to the body. | ||
| // this->addShapeToBody(body, &fixtureDef); | ||
| } | ||
| //it's all gone, will we ever rebuild | ||
| delete this->world; | ||
| //Oh, that was quick, set it back up again! | ||
| this->initializeWorld(); | ||
| } | ||
| IESoRWorld::IESoRWorld() | ||
| { | ||
| this->initializeWorld(); | ||
| // this->interpolation =0; | ||
| // accumulator = 0; | ||
| // desiredFPS = 60; | ||
| // simulationRate = 1.0 / desiredFPS; | ||
| // radians = 0; | ||
| // //if we need to simulate a certain amount of time, we refuse above a certain amount | ||
| // maxFrameSize = .35; | ||
| // //this->bodyList = new vector<PhysicsID*>(); | ||
| // //this->shapeList = new vector<PhysicsID*>(); | ||
| // //this->bodyList = new Json::Value(Json::arrayValue); | ||
| // //this->shapeList = new Json::Value(Json::arrayValue); | ||
| // currentSize = b2Vec2(200, 150); | ||
| // // Define the gravity vector. | ||
| // b2Vec2 gravity(0.0f, -15.0f); | ||
| // // Construct a world object, which will hold and simulate the rigid bodies. | ||
| // this->world = new b2World(gravity); | ||
| // this->world->SetAutoClearForces(false); | ||
| // // Define the ground body. | ||
| // b2BodyDef groundBodyDef; | ||
| // groundBodyDef.type = b2_staticBody; | ||
| // groundBodyDef.position.Set(0.0f, -18.0f); | ||
| // // Call the body factory which allocates memory for the ground body | ||
| // // from a pool and creates the ground box shape (also from a pool). | ||
| // // The body is also added to the world. | ||
| // b2Body* groundBody = this->addBodyToWorld("ground", &groundBodyDef);//this->world->CreateBody(&groundBodyDef); | ||
| // //b2Body* groundBody = this->world->CreateBody(&groundBodyDef); | ||
| // // Define the ground box shape. | ||
| // b2PolygonShape groundBox; | ||
| // // The extents are the half-widths of the box. | ||
| // groundBox.SetAsBox(350.0, 10.0); | ||
| // // Add the ground fixture to the ground body. | ||
| // this->addShapeToBody(groundBody, &groundBox, 0.0f); | ||
| // //groundBody->CreateFixture(&groundBox, 0.0f); | ||
| // // b2Vec2 canvas(200, 150); | ||
| // //this->loadBodyIntoWorld(inBody, canvas); | ||
| // // Define the dynamic body. We set its position and call the body factory. | ||
| // b2BodyDef bodyDef; | ||
| // bodyDef.type = b2_dynamicBody; | ||
| // bodyDef.position.Set(0.0f, 24.0f); | ||
| // //add body to world using definition | ||
| // // b2Body* body = this->addBodyToWorld("rect1", &bodyDef); | ||
| // // Define another box shape for our dynamic body. | ||
| // b2PolygonShape dynamicBox; | ||
| // dynamicBox.SetAsBox(5.0f, 5.0f); | ||
| // // Define the dynamic body fixture. | ||
| // b2FixtureDef fixtureDef; | ||
| // fixtureDef.shape = &dynamicBox; | ||
| // fixtureDef.restitution = .5; | ||
| // // Set the box density to be non-zero, so it will be dynamic. | ||
| // fixtureDef.density = 1.0f; | ||
| // // Override the default friction. | ||
| // fixtureDef.friction = 0.3f; | ||
| // // Add the shape to the body. | ||
| // // this->addShapeToBody(body, &fixtureDef); | ||
| // Define the circle body. We set its position and call the body factory. | ||
| b2BodyDef cDef; | ||
| cDef.type = b2_dynamicBody; | ||
| cDef.position.Set(10.0f, 24.0f); | ||
| // // Define the circle body. We set its position and call the body factory. | ||
| // b2BodyDef cDef; | ||
| // cDef.type = b2_dynamicBody; | ||
| // cDef.position.Set(10.0f, 24.0f); | ||
| //add body to world using definition | ||
| // body = this->addBodyToWorld("circleTest", &cDef); | ||
| // //add body to world using definition | ||
| // // body = this->addBodyToWorld("circleTest", &cDef); | ||
| // Define another box shape for our dynamic body. | ||
| b2CircleShape dCircle; | ||
| dCircle.m_radius = 5.0; | ||
| // // Define another box shape for our dynamic body. | ||
| // b2CircleShape dCircle; | ||
| // dCircle.m_radius = 5.0; | ||
| // Define the dynamic body fixture. | ||
| b2FixtureDef circleDef; | ||
| circleDef.shape = &dCircle; | ||
| circleDef.restitution = .5; | ||
| // // Define the dynamic body fixture. | ||
| // b2FixtureDef circleDef; | ||
| // circleDef.shape = &dCircle; | ||
| // circleDef.restitution = .5; | ||
| // Set the box density to be non-zero, so it will be dynamic. | ||
| circleDef.density = 1.0f; | ||
| // // Set the box density to be non-zero, so it will be dynamic. | ||
| // circleDef.density = 1.0f; | ||
| // Override the default friction. | ||
| circleDef.friction = 0.3f; | ||
| // // Override the default friction. | ||
| // circleDef.friction = 0.3f; | ||
| // Add the shape to the body. | ||
| // this->addShapeToBody(body, &circleDef); | ||
| // // Add the shape to the body. | ||
| // // this->addShapeToBody(body, &circleDef); | ||
| //Add some forces! | ||
| //body->ApplyAngularImpulse(.4, true); | ||
| // //Add some forces! | ||
| // //body->ApplyAngularImpulse(.4, true); | ||
| // body->ApplyTorque(150, true); | ||
| b2Vec2 pulse(70, 0); | ||
| b2Vec2 o(0,3); | ||
| // // body->ApplyTorque(150, true); | ||
| // b2Vec2 pulse(70, 0); | ||
| // b2Vec2 o(0,3); | ||
| // body->ApplyLinearImpulse(pulse, o, true); | ||
@@ -363,2 +469,61 @@ | ||
| Json::Value IESoRWorld::jBodyCenterOfMass() | ||
| { | ||
| //ready for x and y calculations | ||
| double x = 0; double y = 0; | ||
| double bodyCount = 0.0; | ||
| //loop through loaded body map | ||
| for (std::map<std::string,b2Body*>::iterator it=loadedBodyMap.begin(); it!=loadedBodyMap.end(); ++it) | ||
| { | ||
| b2Body* body = it->second; | ||
| b2CircleShape* circle = (b2CircleShape*)body->GetFixtureList()->GetShape(); | ||
| //some voodoo math here -- basically correct for the shape being all wacky and the body contorted | ||
| b2Vec2 v = b2Mul(body->GetTransform(), circle->m_p); | ||
| // printf("COM calc: (%f, %f)\n", v.x, v.y); | ||
| //add the x | ||
| x += v.x; | ||
| //add the y | ||
| y += v.y; | ||
| bodyCount += 1.0; | ||
| //done! | ||
| } | ||
| //nothing to see here -- if you're 0 bodies -- bump to one for the division | ||
| if(bodyCount == 0.0) | ||
| bodyCount = 1.0; | ||
| //set up our json value to send back | ||
| Json::Value xy; | ||
| //store x and y | ||
| xy["x"] = x/bodyCount; | ||
| xy["y"] = y/bodyCount; | ||
| return xy; | ||
| } | ||
| //build it and they shall come | ||
| std::string IESoRWorld::bodyCenterOfMass() | ||
| { | ||
| //turn that from upside down, let's find our center of mass! | ||
| Json::Value xy = this->jBodyCenterOfMass(); | ||
| //easy -- piece together the x and y coordinates in a json friendly way :) | ||
| return "{ \"x\": " + dubString(xy["x"].asDouble()) + ", \"y\": " + dubString(xy["y"].asDouble()) + "}"; | ||
| // var shape = body.GetFixtureList().GetShape(); | ||
| // var cInfo = {center:b2Math.MulX(dBody.m_xf, circle.m_p) , | ||
| // radius:this.drawScale*circle.m_radius }; | ||
| } | ||
| //converts a b2Vec point into a json object | ||
@@ -623,3 +788,3 @@ Json::Value positionToJSONValue(b2Vec2 vec) | ||
| printf(" Widht %f, height: %f \n", canvasWidth, canvasHeight); | ||
| // printf(" Widht %f, height: %f \n", canvasWidth, canvasHeight); | ||
@@ -652,2 +817,6 @@ //Grab an array of nodes from our json object | ||
| // printf("Pre-y height: %f, max: %f, min: %f\n", (maxY - minY), maxY, minY); | ||
| // printf("Pre-y node count: %d\n", oNodes.size()); | ||
| //We loop through all of our nodes | ||
@@ -663,2 +832,5 @@ for (int i=0; i < oNodes.size(); i++) | ||
| // printf("node %d (X,Y) : (%f, %f)\n", i, nodeX, nodeY); | ||
| //here we actually modify the x and y values to fit into a certain sized box depending on the initial screen size/physics world size | ||
@@ -679,5 +851,11 @@ xScaled = (nodeX)/divideForMax* maxAllowedWidth; | ||
| // printf("Y seen: %f\n", yScaled); | ||
| //need to increment the body id so we don't overwrite previous object | ||
| bodyID++; | ||
| } | ||
| // printf("\n\nX width: %f, max: %f, min: %f\n", (maxX - minX), maxX, minX); | ||
| // printf("\n\nY height: %f, max: %f, min: %f\n", (maxY - minY), maxY, minY); | ||
@@ -922,6 +1100,6 @@ //We use movex, movey to center our creature in world space after creation | ||
| printf("Body prep: %i, nodeCount: %i, connCount: %i \n", | ||
| oBodyCount, | ||
| inBody["nodes"].size(), | ||
| inBody["connections"].size()); | ||
| // printf("Body prep: %i, nodeCount: %i, connCount: %i \n", | ||
| // oBodyCount, | ||
| // inBody["nodes"].size(), | ||
| // inBody["connections"].size()); | ||
@@ -931,19 +1109,24 @@ //here we use our body information to create all the necessary body additions to the world | ||
| //we'll quickly map and ID into a json point value | ||
| map<string, Json::Value> entityMap; | ||
| int cnt=0; | ||
| //this was we can access locations by the bodyID while determining connection distance | ||
| //push our bodies into the system so that our joints have bodies to connect to | ||
| this->setBodies(&entities); | ||
| //simple holder for our entities | ||
| std::map<string, Json::Value> entityMap; | ||
| //now loop through our created bodies, and use our body ids to get all of our nodes | ||
| for (std::vector<Json::Value>::iterator it = entities.begin() ; it != entities.end(); ++it) | ||
| { | ||
| Json::Value e = *it; | ||
| printf("bID %s \n", e["bodyID"].asString().c_str()); | ||
| entityMap[e["bodyID"].asString()] = e; | ||
| cnt++; | ||
| } | ||
| printf("Body Map prepared: %i \n", cnt); | ||
| //pull our body idenifier from the entities object | ||
| std::string bID = e["bodyID"].asString(); | ||
| //story the loaded node in the loadedBodyMap | ||
| this->loadedBodyMap[bID] = this->bodyMap[bID]; | ||
| //push our bodies into the system so that our joints have bodies to connect to | ||
| this->setBodies(&entities); | ||
| //looking to map this body id to the entity itself for later reference | ||
| //we'll quickly map and ID into a json point value | ||
| //entity map represent all of our bodies! | ||
| entityMap[bID] = e; | ||
| } | ||
@@ -963,3 +1146,3 @@ //Did we use LEO to calculate our body information -- affects the indexing procedure | ||
| printf("Conns to eval: %i \n", connections.size()); | ||
| // printf("Conns to eval: %i \n", connections.size()); | ||
| int connSize = connections.size(); | ||
@@ -970,3 +1153,3 @@ | ||
| { | ||
| printf("Conn %i start \n", i); | ||
| // printf("Conn %i start \n", i); | ||
| //grab connection from our array | ||
@@ -978,6 +1161,6 @@ Json::Value connectionObject = connections[i]; | ||
| printf("Conn to eval: %s sID: %i, tID: %i \n", | ||
| write.write(connectionObject).c_str(), | ||
| connectionObject["sourceID"].asInt64(), | ||
| connectionObject["targetID"].asInt64()); | ||
| // printf("Conn to eval: %s sID: %i, tID: %i \n", | ||
| // write.write(connectionObject).c_str(), | ||
| // connectionObject["sourceID"].asInt64(), | ||
| // connectionObject["targetID"].asInt64()); | ||
@@ -987,3 +1170,3 @@ long sID = connectionObject["sourceID"].asInt64();//atoi(connectionObject["sourceID"].asString().c_str()); | ||
| printf("Conn to eval: %i - %i \n", sID, tID); | ||
| // printf("Conn to eval: %i - %i \n", sID, tID); | ||
@@ -1027,3 +1210,3 @@ | ||
| printf("Amp: %d, cutoff: %d \n", amp, amplitudeCutoff); | ||
| // printf("Amp: %d, cutoff: %d \n", amp, amplitudeCutoff); | ||
@@ -1059,2 +1242,10 @@ if (amp < amplitudeCutoff) | ||
| //but we can do better! | ||
| //we can get the current center of mass | ||
| Json::Value com = this->jBodyCenterOfMass(); | ||
| //stash our center of mass, yo | ||
| morphology["comX"] = com["x"].asDouble(); | ||
| morphology["comY"] = com["y"].asDouble(); | ||
| //remove the concept of totalNodes since we have mass | ||
@@ -1061,0 +1252,0 @@ //morphology should now have width/height, startX/startY, and mass |
@@ -44,4 +44,9 @@ #ifndef IESORWORLD_H | ||
| void clearWorld(); | ||
| //return the loaded body center of mass -- as a stringified json value | ||
| std::string bodyCenterOfMass(); | ||
| Json::Value jBodyCenterOfMass(); | ||
| private: | ||
@@ -58,2 +63,4 @@ //Json::Value* bodyList; | ||
| void initializeWorld(); | ||
| double modifyFrameTime(double fTime); | ||
@@ -66,2 +73,5 @@ | ||
| //keep a reference to loaded bodies | ||
| std::map<std::string, b2Body*> loadedBodyMap; | ||
| //keep a reference to every body according to ID | ||
@@ -68,0 +78,0 @@ std::map<std::string, b2Body*> bodyMap; |
@@ -40,7 +40,12 @@ #define BUILDING_NODE_EXTENSION | ||
| FunctionTemplate::New(GetWorldDrawList)->GetFunction()); | ||
| //for reseting worlds | ||
| tpl->PrototypeTemplate()->Set(String::NewSymbol("clearWorld"), | ||
| FunctionTemplate::New(ClearWorld)->GetFunction()); | ||
| //grab the current center of mass of a loaded object -- for fitness eval! | ||
| tpl->PrototypeTemplate()->Set(String::NewSymbol("bodyCenterOfMass"), | ||
| FunctionTemplate::New(BodyCenterOfMass)->GetFunction()); | ||
| constructor = Persistent<Function>::New(tpl->GetFunction()); | ||
@@ -166,6 +171,40 @@ exports->Set(String::NewSymbol("iesorWorld"), constructor); | ||
| Handle<Value> IESoRWrap::ClearWorld(const Arguments& args) { | ||
| HandleScope scope; | ||
| //unwrap our shiny new price | ||
| IESoRWrap* obj = ObjectWrap::Unwrap<IESoRWrap>(args.This()); | ||
| //get the directory | ||
| IESoRDirector* director = obj->Director(); | ||
| //no arguments, just destroy the worldly information, mwahahaha | ||
| director->World()->clearWorld(); | ||
| return scope.Close(Null()); | ||
| } | ||
| Handle<Value> IESoRWrap::BodyCenterOfMass(const Arguments& args) { | ||
| HandleScope scope; | ||
| //unwrap our shiny new price | ||
| IESoRWrap* obj = ObjectWrap::Unwrap<IESoRWrap>(args.This()); | ||
| //get the directory | ||
| IESoRDirector* director = obj->Director(); | ||
| //no arguments, just grab the loaded center of mass -- or empty -- i don't care | ||
| std::string com = director->World()->bodyCenterOfMass(); | ||
| //in the future, we might have multiple bodies in a world -- prob not though | ||
| return scope.Close(String::New(com.c_str())); | ||
| } | ||
@@ -26,7 +26,9 @@ #ifndef WORLDWRAPPER_H | ||
| static Handle<Value> LoadBodyFromNetwork(const Arguments& args); | ||
| static Handle<Value> BodyCenterOfMass(const Arguments& args); | ||
| static Handle<Value> SimulateWorldMS(const Arguments& args); | ||
| static Handle<Value> GetWorldDrawList(const Arguments& args); | ||
| static Handle<Value> ConvertNetworkToBody(const Arguments& args); | ||
| static Handle<Value> ClearWorld(const Arguments& args); | ||
| }; | ||
| #endif |
@@ -27,3 +27,2 @@ // This loads our extension in the iesor variable. | ||
| //simulate for 1/2 second | ||
@@ -30,0 +29,0 @@ var simTimeMS = 500; |
+2
-2
| { | ||
| "name": "node-iesor", | ||
| "version": "0.0.3", | ||
| "version": "0.0.4", | ||
| "description": "Node.js wrapper around a C++ IESoR simulation. Indirectly Encoded SodaRace (IESoR) is a research domain for simulating Sodarace inspired two-dimensional ambulating creatures. ", | ||
@@ -30,2 +30,2 @@ "main": "node-iesor/build/Release/nodeiesor.node", | ||
| "homepage": "https://github.com/OptimusLime/node-iesor" | ||
| } | ||
| } |
1003439
0.78%