Created
September 28, 2013 22:35
-
-
Save musicm122/6747466 to your computer and use it in GitHub Desktop.
around line 213 of b2dJson.cpp
case b2Shape::e_edge: { b2EdgeShape* edge = (b2EdgeShape*)shape; vecToJson("vertex1", edge->m_vertex1, fixtureValue["edge"]); vecToJson("vertex2", edge->m_vertex2, fixtureValue["edge"]); if ( edge->m_hasVertex0 ) fixtureValue["edge"]["hasVertex0"] = true; if ( edge->m_hasVertex3 ) fixtureValue["edge"]["hasVertex3"]…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Author: Chris Campbell - www.iforce2d.net | |
| * | |
| * This software is provided 'as-is', without any express or implied | |
| * warranty. In no event will the authors be held liable for any damages | |
| * arising from the use of this software. | |
| * Permission is granted to anyone to use this software for any purpose, | |
| * including commercial applications, and to alter it and redistribute it | |
| * freely, subject to the following restrictions: | |
| * 1. The origin of this software must not be misrepresented; you must not | |
| * claim that you wrote the original software. If you use this software | |
| * in a product, an acknowledgment in the product documentation would be | |
| * appreciated but is not required. | |
| * 2. Altered source versions must be plainly marked as such, and must not be | |
| * misrepresented as being the original software. | |
| * 3. This notice may not be removed or altered from any source distribution. | |
| */ | |
| #include "StdAfx.h" | |
| #include <istream> | |
| #include <fstream> | |
| #include "b2dJson.h" | |
| #include "json/json.h" | |
| #include "b2dJsonImage.h" | |
| #include "Infrastructure\Log.h" | |
| using namespace std; | |
| #define sysLog CompoundLog::GetSystemLog() | |
| inline bool b2dJsonImage_renderOrder_ascending(const b2dJsonImage* a, const b2dJsonImage* b) | |
| { | |
| return a->renderOrder < b->renderOrder; | |
| } | |
| b2dJson::b2dJson(bool useHumanReadableFloats) | |
| { | |
| m_useHumanReadableFloats = useHumanReadableFloats; | |
| } | |
| b2dJson::~b2dJson() | |
| { | |
| for (int i = 0; i < (int)m_images.size(); i++) | |
| delete m_images[i]; | |
| for (std::map<void*,b2dJsonCustomProperties*>::iterator it = m_customPropertiesMap.begin(); it != m_customPropertiesMap.end(); ++it) | |
| delete it->second; | |
| } | |
| Json::Value b2dJson::writeToValue(b2World *world) | |
| { | |
| if (!world) | |
| return Json::Value(); | |
| return b2j(world); | |
| } | |
| std::string b2dJson::writeToString(b2World* world) | |
| { | |
| if (!world) | |
| return std::string(); | |
| Json::StyledWriter writer; | |
| return writer.write( b2j(world) ); | |
| } | |
| bool b2dJson::writeToFile(b2World* world, const char* filename) | |
| { | |
| if ( !world || !filename ) | |
| return false; | |
| std::ofstream ofs; | |
| ofs.open(filename, std::ios::out); | |
| if (!ofs) { | |
| std::cout << "Could not open file " << filename << " for writing\n"; | |
| return false; | |
| } | |
| Json::StyledStreamWriter writer(" "); | |
| writer.write( ofs, b2j(world) ); | |
| ofs.close(); | |
| return true; | |
| } | |
| Json::Value b2dJson::b2j(b2World* world) | |
| { | |
| m_bodyToIndexMap.clear(); | |
| m_jointToIndexMap.clear(); | |
| Json::Value worldValue; | |
| vecToJson("gravity", world->GetGravity(), worldValue); | |
| worldValue["allowSleep"] = world->GetAllowSleeping(); | |
| worldValue["autoClearForces"] = world->GetAutoClearForces(); | |
| worldValue["warmStarting"] = world->GetWarmStarting(); | |
| worldValue["continuousPhysics"] = world->GetContinuousPhysics(); | |
| worldValue["subStepping"] = world->GetSubStepping(); | |
| //worldValue["hasDestructionListener"] = world->HasDestructionListener(); | |
| //worldValue["hasContactFilter"] = world->HasContactFilter(); | |
| //worldValue["hasContactListener"] = world->HasContactListener(); | |
| int i = 0; | |
| for (b2Body* body = world->GetBodyList(); body; body = body->GetNext()) { | |
| m_bodyToIndexMap[body] = i; | |
| worldValue["body"][i] = b2j(body); | |
| i++; | |
| } | |
| //need two passes for joints because gear joints reference other joints | |
| i = 0; | |
| for (b2Joint* joint = world->GetJointList(); joint; joint = joint->GetNext()) { | |
| if ( joint->GetType() == e_gearJoint ) | |
| continue; | |
| worldValue["joint"][i] = b2j(joint); | |
| m_jointToIndexMap[joint] = i; | |
| i++; | |
| } | |
| for (b2Joint* joint = world->GetJointList(); joint; joint = joint->GetNext()) { | |
| if ( joint->GetType() != e_gearJoint ) | |
| continue; | |
| worldValue["joint"][i] = b2j(joint); | |
| m_jointToIndexMap[joint] = i; | |
| i++; | |
| } | |
| i = 0; | |
| { | |
| std::map<b2dJsonImage*,string>::iterator it = m_imageToNameMap.begin(); | |
| std::map<b2dJsonImage*,string>::iterator end = m_imageToNameMap.end(); | |
| while (it != end) { | |
| b2dJsonImage* image = it->first; | |
| worldValue["image"][i] = b2j(image); | |
| i++; | |
| ++it; | |
| } | |
| } | |
| Json::Value customPropertyValue = writeCustomPropertiesToJson(NULL); | |
| if ( ! customPropertyValue.empty() ) | |
| worldValue["customProperties"] = customPropertyValue; | |
| m_bodyToIndexMap.clear(); | |
| m_jointToIndexMap.clear(); | |
| return worldValue; | |
| } | |
| Json::Value b2dJson::b2j(b2Body* body) | |
| { | |
| Json::Value bodyValue; | |
| string bodyName = getBodyName(body); | |
| if ( bodyName != "" ) | |
| bodyValue["name"] = bodyName; | |
| bodyValue["type"] = body->GetType(); | |
| switch( body->GetType() ) | |
| { | |
| case b2_staticBody: | |
| bodyValue["type"].setComment("//static", Json::commentAfterOnSameLine); | |
| break; | |
| case b2_dynamicBody: | |
| bodyValue["type"].setComment("//dynamic", Json::commentAfterOnSameLine); | |
| break; | |
| case b2_kinematicBody: | |
| bodyValue["type"].setComment("//kinematic", Json::commentAfterOnSameLine); | |
| break; | |
| } | |
| vecToJson("position", body->GetPosition(), bodyValue); | |
| floatToJson("angle", body->GetAngle(), bodyValue ); | |
| vecToJson("linearVelocity", body->GetLinearVelocity(), bodyValue); | |
| floatToJson("angularVelocity", body->GetAngularVelocity(), bodyValue); | |
| if ( body->GetLinearDamping() != 0 ) | |
| floatToJson("linearDamping", body->GetLinearDamping(), bodyValue); | |
| if ( body->GetAngularDamping() != 0 ) | |
| floatToJson("angularDamping", body->GetAngularDamping(), bodyValue); | |
| if ( body->GetGravityScale() != 1 ) | |
| floatToJson("gravityScale", body->GetGravityScale(), bodyValue); | |
| if ( body->IsBullet() ) | |
| bodyValue["bullet"] = true; | |
| if ( ! body->IsSleepingAllowed() ) | |
| bodyValue["allowSleep"] = false; | |
| if ( body->IsAwake() ) | |
| bodyValue["awake"] = true; | |
| if ( ! body->IsActive() ) | |
| bodyValue["active"] = false; | |
| if ( body->IsFixedRotation() ) | |
| bodyValue["fixedRotation"] = true; | |
| b2MassData massData; | |
| body->GetMassData(&massData); | |
| if ( massData.mass != 0 ) | |
| floatToJson("massData-mass", massData.mass, bodyValue); | |
| if ( massData.center.x != 0 || massData.center.y != 0 ) | |
| vecToJson("massData-center", massData.center, bodyValue); | |
| if ( massData.I != 0 ) | |
| floatToJson("massData-I", massData.I, bodyValue); | |
| int i = 0; | |
| for (b2Fixture* fixture = body->GetFixtureList(); fixture; fixture = fixture->GetNext()) | |
| bodyValue["fixture"][i++] = b2j(fixture); | |
| Json::Value customPropertyValue = writeCustomPropertiesToJson(body); | |
| if ( ! customPropertyValue.empty() ) | |
| bodyValue["customProperties"] = customPropertyValue; | |
| return bodyValue; | |
| } | |
| Json::Value b2dJson::b2j(b2Fixture *fixture) | |
| { | |
| Json::Value fixtureValue; | |
| string fixtureName = getFixtureName(fixture); | |
| if ( fixtureName != "" ) | |
| fixtureValue["name"] = fixtureName; | |
| if ( fixture->GetRestitution() != 0 ) | |
| floatToJson("restitution", fixture->GetRestitution(), fixtureValue); | |
| if ( fixture->GetFriction() != 0 ) | |
| floatToJson("friction", fixture->GetFriction(), fixtureValue); | |
| if ( fixture->GetDensity() != 0 ) | |
| floatToJson("density", fixture->GetDensity(), fixtureValue); | |
| if ( fixture->IsSensor() ) | |
| fixtureValue["sensor"] = true; | |
| b2Filter filter = fixture->GetFilterData(); | |
| if ( filter.categoryBits != 0x0001 ) | |
| fixtureValue["filter-categoryBits"] = filter.categoryBits; | |
| if ( filter.maskBits != 0xffff ) | |
| fixtureValue["filter-maskBits"] = filter.maskBits; | |
| if ( filter.groupIndex != 0 ) | |
| fixtureValue["filter-groupIndex"] = filter.groupIndex; | |
| b2Shape* shape = fixture->GetShape(); | |
| switch (shape->GetType()) | |
| { | |
| case b2Shape::e_circle: | |
| { | |
| b2CircleShape* circle = (b2CircleShape*)shape; | |
| floatToJson("radius", circle->m_radius, fixtureValue["circle"]); | |
| vecToJson("center", circle->m_p, fixtureValue["circle"]); | |
| } | |
| break; | |
| case b2Shape::e_edge: | |
| { | |
| b2EdgeShape* edge = (b2EdgeShape*)shape; | |
| vecToJson("vertex1", edge->m_vertex1, fixtureValue["edge"]); | |
| vecToJson("vertex2", edge->m_vertex2, fixtureValue["edge"]); | |
| if ( edge->m_hasVertex0 ) | |
| fixtureValue["edge"]["hasVertex0"] = true; | |
| if ( edge->m_hasVertex3 ) | |
| fixtureValue["edge"]["hasVertex3"] = true; | |
| if ( edge->m_hasVertex0 ) | |
| vecToJson("vertex0", edge->m_vertex0, fixtureValue["edge"]); | |
| if ( edge->m_hasVertex3 ) | |
| vecToJson("vertex3", edge->m_vertex3, fixtureValue["edge"]); | |
| } | |
| break; | |
| case b2Shape::e_chain: | |
| { | |
| b2ChainShape* chain = (b2ChainShape*)shape; | |
| int32 count = chain->m_count; | |
| const b2Vec2* vertices = chain->m_vertices; | |
| for (int32 i = 0; i < count; ++i) | |
| vecToJson("vertices", vertices[i], fixtureValue["chain"], i); | |
| if ( chain->m_hasPrevVertex ) | |
| fixtureValue["chain"]["hasPrevVertex"] = true; | |
| if ( chain->m_hasNextVertex ) | |
| fixtureValue["chain"]["hasNextVertex"] = true; | |
| if ( chain->m_hasPrevVertex ) | |
| vecToJson("prevVertex", chain->m_prevVertex, fixtureValue["chain"]); | |
| if ( chain->m_hasNextVertex ) | |
| vecToJson("nextVertex", chain->m_nextVertex, fixtureValue["chain"]); | |
| } | |
| break; | |
| case b2Shape::e_polygon: | |
| { | |
| b2PolygonShape* poly = (b2PolygonShape*)shape; | |
| int32 vertexCount = poly->GetVertexCount(); | |
| b2Assert(vertexCount <= b2_maxPolygonVertices); | |
| for (int32 i = 0; i < vertexCount; ++i) | |
| vecToJson("vertices", poly->m_vertices[i], fixtureValue["polygon"], i); | |
| } | |
| break; | |
| default: | |
| std::cout << "Unknown shape type : " << shape->GetType() << std::endl; | |
| } | |
| Json::Value customPropertyValue = writeCustomPropertiesToJson(fixture); | |
| if ( ! customPropertyValue.empty() ) | |
| fixtureValue["customProperties"] = customPropertyValue; | |
| return fixtureValue; | |
| } | |
| Json::Value b2dJson::b2j(b2Joint* joint) | |
| { | |
| Json::Value jointValue; | |
| int bodyIndexA = lookupBodyIndex( joint->GetBodyA() ); | |
| int bodyIndexB = lookupBodyIndex( joint->GetBodyB() ); | |
| jointValue["bodyA"] = bodyIndexA; | |
| jointValue["bodyB"] = bodyIndexB; | |
| if ( joint->GetCollideConnected() ) | |
| jointValue["collideConnected"] = true; | |
| string jointName = getJointName(joint); | |
| if ( jointName != "" ) | |
| jointValue["name"] = jointName; | |
| b2Body* bodyA = joint->GetBodyA(); | |
| b2Body* bodyB = joint->GetBodyB(); | |
| switch ( joint->GetType() ) | |
| { | |
| case e_revoluteJoint: | |
| { | |
| jointValue["type"] = "revolute"; | |
| b2RevoluteJoint* revoluteJoint = (b2RevoluteJoint*)joint; | |
| vecToJson("anchorA", bodyA->GetLocalPoint(revoluteJoint->GetAnchorA()), jointValue); | |
| vecToJson("anchorB", bodyB->GetLocalPoint(revoluteJoint->GetAnchorB()), jointValue); | |
| floatToJson("refAngle", bodyB->GetAngle() - bodyA->GetAngle() - revoluteJoint->GetJointAngle(), jointValue); | |
| floatToJson("jointSpeed", revoluteJoint->GetJointSpeed(), jointValue); | |
| jointValue["enableLimit"] = revoluteJoint->IsLimitEnabled(); | |
| floatToJson("lowerLimit", revoluteJoint->GetLowerLimit(), jointValue); | |
| floatToJson("upperLimit", revoluteJoint->GetUpperLimit(), jointValue); | |
| jointValue["enableMotor"] = revoluteJoint->IsMotorEnabled(); | |
| floatToJson("motorSpeed", revoluteJoint->GetMotorSpeed(), jointValue); | |
| floatToJson("maxMotorTorque", revoluteJoint->GetMaxMotorTorque(), jointValue); | |
| } | |
| break; | |
| case e_prismaticJoint: | |
| { | |
| jointValue["type"] = "prismatic"; | |
| b2PrismaticJoint* prismaticJoint = (b2PrismaticJoint*)joint; | |
| vecToJson("anchorA", bodyA->GetLocalPoint(prismaticJoint->GetAnchorA()), jointValue); | |
| vecToJson("anchorB", bodyB->GetLocalPoint(prismaticJoint->GetAnchorB()), jointValue); | |
| vecToJson("localAxisA", prismaticJoint->GetLocalAxisA(), jointValue); | |
| floatToJson("refAngle", prismaticJoint->GetReferenceAngle(), jointValue); | |
| jointValue["enableLimit"] = prismaticJoint->IsLimitEnabled(); | |
| floatToJson("lowerLimit", prismaticJoint->GetLowerLimit(), jointValue); | |
| floatToJson("upperLimit", prismaticJoint->GetUpperLimit(), jointValue); | |
| jointValue["enableMotor"] = prismaticJoint->IsMotorEnabled(); | |
| floatToJson("maxMotorForce", prismaticJoint->GetMaxMotorForce(), jointValue); | |
| floatToJson("motorSpeed", prismaticJoint->GetMotorSpeed(), jointValue); | |
| } | |
| break; | |
| case e_distanceJoint: | |
| { | |
| jointValue["type"] = "distance"; | |
| b2DistanceJoint* distanceJoint = (b2DistanceJoint*)joint; | |
| vecToJson("anchorA", bodyA->GetLocalPoint(distanceJoint->GetAnchorA()), jointValue); | |
| vecToJson("anchorB", bodyB->GetLocalPoint(distanceJoint->GetAnchorB()), jointValue); | |
| floatToJson("length", distanceJoint->GetLength(), jointValue); | |
| floatToJson("frequency", distanceJoint->GetFrequency(), jointValue); | |
| floatToJson("dampingRatio", distanceJoint->GetDampingRatio(), jointValue); | |
| } | |
| break; | |
| case e_pulleyJoint: | |
| { | |
| jointValue["type"] = "pulley"; | |
| b2PulleyJoint* pulleyJoint = (b2PulleyJoint*)joint; | |
| vecToJson("groundAnchorA", pulleyJoint->GetGroundAnchorA(), jointValue); | |
| vecToJson("groundAnchorB", pulleyJoint->GetGroundAnchorB(), jointValue); | |
| vecToJson("anchorA", bodyA->GetLocalPoint(pulleyJoint->GetAnchorA()), jointValue); | |
| vecToJson("anchorB", bodyB->GetLocalPoint(pulleyJoint->GetAnchorB()), jointValue); | |
| floatToJson("lengthA", (pulleyJoint->GetGroundAnchorA() - pulleyJoint->GetAnchorA()).Length(), jointValue); | |
| floatToJson("lengthB", (pulleyJoint->GetGroundAnchorB() - pulleyJoint->GetAnchorB()).Length(), jointValue); | |
| floatToJson("ratio", pulleyJoint->GetRatio(), jointValue); | |
| } | |
| break; | |
| case e_mouseJoint: | |
| { | |
| jointValue["type"] = "mouse"; | |
| b2MouseJoint* mouseJoint = (b2MouseJoint*)joint; | |
| vecToJson("target", mouseJoint->GetTarget(), jointValue); | |
| vecToJson("anchorB", mouseJoint->GetAnchorB(), jointValue); | |
| floatToJson("maxForce", mouseJoint->GetMaxForce(), jointValue); | |
| floatToJson("frequency", mouseJoint->GetFrequency(), jointValue); | |
| floatToJson("dampingRatio", mouseJoint->GetDampingRatio(), jointValue); | |
| } | |
| break; | |
| case e_gearJoint: | |
| { | |
| jointValue["type"] = "gear"; | |
| b2GearJoint* gearJoint = (b2GearJoint*)joint; | |
| int jointIndex1 = lookupJointIndex( gearJoint->GetJoint1() ); | |
| int jointIndex2 = lookupJointIndex( gearJoint->GetJoint2() ); | |
| jointValue["joint1"] = jointIndex1; | |
| jointValue["joint2"] = jointIndex2; | |
| jointValue["ratio"] = gearJoint->GetRatio(); | |
| } | |
| break; | |
| case e_wheelJoint: | |
| { | |
| jointValue["type"] = "wheel"; | |
| b2WheelJoint* wheelJoint = (b2WheelJoint*)joint; | |
| vecToJson("anchorA", bodyA->GetLocalPoint(wheelJoint->GetAnchorA()), jointValue); | |
| vecToJson("anchorB", bodyB->GetLocalPoint(wheelJoint->GetAnchorB()), jointValue); | |
| vecToJson("localAxisA", wheelJoint->GetLocalAxisA(), jointValue); | |
| jointValue["enableMotor"] = wheelJoint->IsMotorEnabled(); | |
| floatToJson("motorSpeed", wheelJoint->GetMotorSpeed(), jointValue); | |
| floatToJson("maxMotorTorque", wheelJoint->GetMaxMotorTorque(), jointValue); | |
| floatToJson("springFrequency", wheelJoint->GetSpringFrequencyHz(), jointValue); | |
| floatToJson("springDampingRatio", wheelJoint->GetSpringDampingRatio(), jointValue); | |
| } | |
| break; | |
| //case e_motorJoint: | |
| // { | |
| // jointValue["type"] = "motor"; | |
| // b2MotorJoint* motorJoint = (b2MotorJoint*)joint; | |
| // vecToJson("anchorA", bodyA->GetLocalPoint(motorJoint->GetAnchorA()), jointValue); | |
| // vecToJson("anchorB", bodyB->GetLocalPoint(motorJoint->GetAnchorB()), jointValue); | |
| // floatToJson("refAngle", motorJoint->GetAngularOffset(), jointValue); | |
| // floatToJson("maxForce", motorJoint->GetMaxForce(), jointValue); | |
| // floatToJson("maxTorque", motorJoint->GetMaxTorque(), jointValue); | |
| // //floatToJson("correctionFactor", motorJoint->GetCorrectionFactor(), jointValue); | |
| // } | |
| // break; | |
| case e_weldJoint: | |
| { | |
| jointValue["type"] = "weld"; | |
| b2WeldJoint* weldJoint = (b2WeldJoint*)joint; | |
| vecToJson("anchorA", bodyA->GetLocalPoint(weldJoint->GetAnchorA()), jointValue); | |
| vecToJson("anchorB", bodyB->GetLocalPoint(weldJoint->GetAnchorB()), jointValue); | |
| floatToJson("refAngle", weldJoint->GetReferenceAngle(), jointValue); | |
| floatToJson("frequency", weldJoint->GetFrequency(), jointValue); | |
| floatToJson("dampingRatio", weldJoint->GetDampingRatio(), jointValue); | |
| } | |
| break; | |
| case e_frictionJoint: | |
| { | |
| jointValue["type"] = "friction"; | |
| b2FrictionJoint* frictionJoint = (b2FrictionJoint*)joint; | |
| vecToJson("anchorA", bodyA->GetLocalPoint(frictionJoint->GetAnchorA()), jointValue); | |
| vecToJson("anchorB", bodyB->GetLocalPoint(frictionJoint->GetAnchorB()), jointValue); | |
| floatToJson("maxForce", frictionJoint->GetMaxForce(), jointValue); | |
| floatToJson("maxTorque", frictionJoint->GetMaxTorque(), jointValue); | |
| } | |
| break; | |
| case e_ropeJoint: | |
| { | |
| jointValue["type"] = "rope"; | |
| b2RopeJoint* ropeJoint = (b2RopeJoint*)joint; | |
| vecToJson("anchorA", bodyA->GetLocalPoint(ropeJoint->GetAnchorA()), jointValue); | |
| vecToJson("anchorB", bodyB->GetLocalPoint(ropeJoint->GetAnchorB()), jointValue); | |
| floatToJson("maxLength", ropeJoint->GetMaxLength(), jointValue); | |
| } | |
| break; | |
| case e_unknownJoint: | |
| default: | |
| std::cout << "Unknown joint type not stored in snapshot : " << joint->GetType() << std::endl; | |
| } | |
| Json::Value customPropertyValue = writeCustomPropertiesToJson(joint); | |
| if ( ! customPropertyValue.empty() ) | |
| jointValue["customProperties"] = customPropertyValue; | |
| return jointValue; | |
| } | |
| Json::Value b2dJson::b2j(b2dJsonImage *image) | |
| { | |
| Json::Value imageValue; | |
| if ( image->body ) | |
| imageValue["body"] = lookupBodyIndex( image->body ); | |
| else | |
| imageValue["body"] = -1; | |
| if ( image->name != "" ) | |
| imageValue["name"] = image->name; | |
| if ( image->file != "" ) | |
| imageValue["file"] = image->file; | |
| vecToJson("center", image->center, imageValue); | |
| floatToJson("angle", image->angle, imageValue ); | |
| floatToJson("scale", image->scale, imageValue ); | |
| if ( image->flip ) | |
| imageValue["flip"] = true; | |
| floatToJson("opacity", image->opacity, imageValue ); | |
| imageValue["filter"] = image->filter; | |
| floatToJson("renderOrder", image->renderOrder, imageValue ); | |
| bool defaultColorTint = true; | |
| for (int i = 0; i < 4; i++) { | |
| if ( image->colorTint[i] != 255 ) { | |
| defaultColorTint = false; | |
| break; | |
| } | |
| } | |
| if ( !defaultColorTint ) { | |
| for (int i = 0; i < 4; i++) | |
| imageValue["colorTint"][i] = image->colorTint[i]; | |
| } | |
| //image->updateCorners(); | |
| for (int i = 0; i < 4; i++) | |
| vecToJson("corners", image->corners[i], imageValue, i); | |
| //image->updateUVs(); | |
| for (int i = 0; i < 2*image->numPoints; i++) { | |
| vecToJson("glVertexPointer", image->points[i], imageValue, i); | |
| vecToJson("glTexCoordPointer", image->uvCoords[i], imageValue, i); | |
| } | |
| for (int i = 0; i < image->numIndices; i++) | |
| vecToJson("glDrawElements", (unsigned int)image->indices[i], imageValue, i); | |
| Json::Value customPropertyValue = writeCustomPropertiesToJson(image); | |
| if ( ! customPropertyValue.empty() ) | |
| imageValue["customProperties"] = customPropertyValue; | |
| return imageValue; | |
| } | |
| void b2dJson::setBodyName(b2Body* body, const char* name) | |
| { | |
| m_bodyToNameMap[body] = name; | |
| } | |
| void b2dJson::setFixtureName(b2Fixture* fixture, const char* name) | |
| { | |
| m_fixtureToNameMap[fixture] = name; | |
| } | |
| void b2dJson::setJointName(b2Joint* joint, const char* name) | |
| { | |
| m_jointToNameMap[joint] = name; | |
| } | |
| void b2dJson::setImageName(b2dJsonImage* image, const char* name) | |
| { | |
| m_imageToNameMap[image] = name; | |
| } | |
| void b2dJson::addImage(b2dJsonImage *image) | |
| { | |
| setImageName(image, image->name.c_str()); | |
| } | |
| ///////// | |
| b2dJsonCustomProperties *b2dJson::getCustomPropertiesForItem(void *item, bool createIfNotExisting) | |
| { | |
| std::map<void*,b2dJsonCustomProperties*>::iterator it = m_customPropertiesMap.find(item); | |
| if ( it != m_customPropertiesMap.end() ) | |
| return it->second; | |
| if ( !createIfNotExisting ) | |
| return NULL; | |
| b2dJsonCustomProperties* props = new b2dJsonCustomProperties(); | |
| m_customPropertiesMap[item] = props; | |
| return props; | |
| } | |
| void b2dJson::setCustomInt(void* item, string propertyName, int val) { getCustomPropertiesForItem(item, true)->m_customPropertyMap_int[propertyName] = val; } | |
| void b2dJson::setCustomFloat(void* item, string propertyName, float val) { getCustomPropertiesForItem(item, true)->m_customPropertyMap_float[propertyName] = val; } | |
| void b2dJson::setCustomString(void* item, string propertyName, string val) { getCustomPropertiesForItem(item, true)->m_customPropertyMap_string[propertyName] = val; } | |
| void b2dJson::setCustomVector(void* item, string propertyName, b2Vec2 val) { getCustomPropertiesForItem(item, true)->m_customPropertyMap_b2Vec2[propertyName] = val; } | |
| void b2dJson::setCustomBool(void* item, string propertyName, bool val) { getCustomPropertiesForItem(item, true)->m_customPropertyMap_bool[propertyName] = val; } | |
| bool b2dJson::hasCustomInt(void *item, string propertyName) { return getCustomPropertiesForItem(item, false) != NULL && getCustomPropertiesForItem(item, false)->m_customPropertyMap_int.count(propertyName) > 0; } | |
| bool b2dJson::hasCustomFloat(void *item, string propertyName) { return getCustomPropertiesForItem(item, false) != NULL && getCustomPropertiesForItem(item, false)->m_customPropertyMap_float.count(propertyName) > 0; } | |
| bool b2dJson::hasCustomString(void *item, string propertyName) { return getCustomPropertiesForItem(item, false) != NULL && getCustomPropertiesForItem(item, false)->m_customPropertyMap_string.count(propertyName) > 0; } | |
| bool b2dJson::hasCustomVector(void *item, string propertyName) { return getCustomPropertiesForItem(item, false) != NULL && getCustomPropertiesForItem(item, false)->m_customPropertyMap_b2Vec2.count(propertyName) > 0; } | |
| bool b2dJson::hasCustomBool(void *item, string propertyName) { return getCustomPropertiesForItem(item, false) != NULL && getCustomPropertiesForItem(item, false)->m_customPropertyMap_bool.count(propertyName) > 0; } | |
| int b2dJson::getCustomInt(void *item, string propertyName, int defaultVal) | |
| { | |
| b2dJsonCustomProperties* props = getCustomPropertiesForItem(item, false); | |
| if ( !props ) | |
| return defaultVal; | |
| std::map<string,int>::iterator it = props->m_customPropertyMap_int.find(propertyName); | |
| if ( it != props->m_customPropertyMap_int.end() ) | |
| return it->second; | |
| return defaultVal; | |
| } | |
| float b2dJson::getCustomFloat(void *item, string propertyName, float defaultVal) | |
| { | |
| b2dJsonCustomProperties* props = getCustomPropertiesForItem(item, false); | |
| if ( !props ) | |
| return defaultVal; | |
| std::map<string,float>::iterator it = props->m_customPropertyMap_float.find(propertyName); | |
| if ( it != props->m_customPropertyMap_float.end() ) | |
| return it->second; | |
| return defaultVal; | |
| } | |
| string b2dJson::getCustomString(void *item, string propertyName, string defaultVal) | |
| { | |
| b2dJsonCustomProperties* props = getCustomPropertiesForItem(item, false); | |
| if ( !props ) | |
| return defaultVal; | |
| std::map<string,string>::iterator it = props->m_customPropertyMap_string.find(propertyName); | |
| if ( it != props->m_customPropertyMap_string.end() ) | |
| return it->second; | |
| return defaultVal; | |
| } | |
| b2Vec2 b2dJson::getCustomVector(void *item, string propertyName, b2Vec2 defaultVal) | |
| { | |
| b2dJsonCustomProperties* props = getCustomPropertiesForItem(item, false); | |
| if ( !props ) | |
| return defaultVal; | |
| std::map<string,b2Vec2>::iterator it = props->m_customPropertyMap_b2Vec2.find(propertyName); | |
| if ( it != props->m_customPropertyMap_b2Vec2.end() ) | |
| return it->second; | |
| return defaultVal; | |
| } | |
| bool b2dJson::getCustomBool(void *item, string propertyName, bool defaultVal) | |
| { | |
| b2dJsonCustomProperties* props = getCustomPropertiesForItem(item, false); | |
| if ( !props ) | |
| return defaultVal; | |
| std::map<string,bool>::iterator it = props->m_customPropertyMap_bool.find(propertyName); | |
| if ( it != props->m_customPropertyMap_bool.end() ) | |
| return it->second; | |
| return defaultVal; | |
| } | |
| //this define saves us writing out 20 functions which are almost exactly the same | |
| #define IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Type, ucName, lcName, ucValType, lcValType)\ | |
| int b2dJson::get##ucName##ByCustom##ucValType( std::string propertyName, lcValType valueToMatch, std::vector<b2Type*>& items )\ | |
| {\ | |
| set<b2Type*>::iterator it = m_##lcName##WithCustomProperties.begin();\ | |
| set<b2Type*>::iterator end = m_##lcName##WithCustomProperties.end();\ | |
| while (it != end)\ | |
| {\ | |
| b2Type* item = *it;\ | |
| if ( hasCustom##ucValType( item, propertyName ) && getCustom##ucValType( item, propertyName ) == valueToMatch )\ | |
| items.push_back( item );\ | |
| ++it;\ | |
| }\ | |
| return items.size();\ | |
| } | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Body, Bodies, bodies, Int, int) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Body, Bodies, bodies, Float, float) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Body, Bodies, bodies, String, string) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Body, Bodies, bodies, Vector, b2Vec2) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Body, Bodies, bodies, Bool, bool) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Fixture, Fixtures, fixtures, Int, int) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Fixture, Fixtures, fixtures, Float, float) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Fixture, Fixtures, fixtures, String, string) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Fixture, Fixtures, fixtures, Vector, b2Vec2) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Fixture, Fixtures, fixtures, Bool, bool) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Joint, Joints, joints, Int, int) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Joint, Joints, joints, Float, float) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Joint, Joints, joints, String, string) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Joint, Joints, joints, Vector, b2Vec2) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2Joint, Joints, joints, Bool, bool) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2dJsonImage, Images, images, Int, int) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2dJsonImage, Images, images, Float, float) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2dJsonImage, Images, images, String, string) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2dJsonImage, Images, images, Vector, b2Vec2) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_VECTOR(b2dJsonImage, Images, images, Bool, bool) | |
| //this define saves us writing out 20 functions which are almost exactly the same | |
| #define IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Type, ucName, lcName, ucValType, lcValType)\ | |
| b2Type* b2dJson::get##ucName##ByCustom##ucValType( std::string propertyName, lcValType valueToMatch )\ | |
| {\ | |
| set<b2Type*>::iterator it = m_##lcName##WithCustomProperties.begin();\ | |
| set<b2Type*>::iterator end = m_##lcName##WithCustomProperties.end();\ | |
| while (it != end)\ | |
| {\ | |
| b2Type* item = *it;\ | |
| if ( hasCustom##ucValType( item, propertyName ) && getCustom##ucValType( item, propertyName ) == valueToMatch )\ | |
| return item;\ | |
| ++it;\ | |
| }\ | |
| return NULL;\ | |
| } | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Body, Body, bodies, Int, int) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Body, Body, bodies, Float, float) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Body, Body, bodies, String, string) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Body, Body, bodies, Vector, b2Vec2) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Body, Body, bodies, Bool, bool) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Fixture, Fixture, fixtures, Int, int) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Fixture, Fixture, fixtures, Float, float) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Fixture, Fixture, fixtures, String, string) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Fixture, Fixture, fixtures, Vector, b2Vec2) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Fixture, Fixture, fixtures, Bool, bool) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Joint, Joint, joints, Int, int) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Joint, Joint, joints, Float, float) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Joint, Joint, joints, String, string) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Joint, Joint, joints, Vector, b2Vec2) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2Joint, Joint, joints, Bool, bool) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2dJsonImage, Image, images, Int, int) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2dJsonImage, Image, images, Float, float) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2dJsonImage, Image, images, String, string) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2dJsonImage, Image, images, Vector, b2Vec2) | |
| IMPLEMENT_GET_BY_CUSTOM_PROPERTY_FUNCTIONS_SINGLE(b2dJsonImage, Image, images, Bool, bool) | |
| Json::Value b2dJson::writeCustomPropertiesToJson(void* item) | |
| { | |
| Json::Value customPropertiesValue; | |
| b2dJsonCustomProperties* props = getCustomPropertiesForItem(item, false); | |
| if ( !props ) | |
| return customPropertiesValue; | |
| int i = 0; | |
| #define FILL_CUSTOM_PROPERTY_JSON_VALUE(theName,theType)\ | |
| for (std::map<string,theType>::iterator it = props->m_customPropertyMap_##theType.begin(); it != props->m_customPropertyMap_##theType.end(); ++it) {\ | |
| Json::Value propValue;\ | |
| propValue["name"] = it->first;\ | |
| propValue[""#theName] = it->second;\ | |
| customPropertiesValue[i++] = propValue;\ | |
| } | |
| FILL_CUSTOM_PROPERTY_JSON_VALUE(int,int) | |
| FILL_CUSTOM_PROPERTY_JSON_VALUE(float,float) | |
| FILL_CUSTOM_PROPERTY_JSON_VALUE(string,string) | |
| //FILL_CUSTOM_PROPERTY_JSON_VALUE(vec2,b2Vec2) handled separately below | |
| FILL_CUSTOM_PROPERTY_JSON_VALUE(bool,bool) | |
| for (std::map<string,b2Vec2>::iterator it = props->m_customPropertyMap_b2Vec2.begin(); it != props->m_customPropertyMap_b2Vec2.end(); ++it) { | |
| Json::Value propValue; | |
| propValue["name"] = it->first; | |
| vecToJson("vec2", it->second, propValue); | |
| customPropertiesValue[i++] = propValue; | |
| } | |
| return customPropertiesValue; | |
| } | |
| #define IMPLEMENT_READ_CUSTOM_PROPERTIES_FROM_JSON(b2Type)\ | |
| void b2dJson::readCustomPropertiesFromJson(b2Type* item, Json::Value value)\ | |
| {\ | |
| if ( ! item )\ | |
| return;\ | |
| if ( ! value.isMember("customProperties") )\ | |
| return;\ | |
| \ | |
| int i = 0;\ | |
| Json::Value propValue = value["customProperties"][i++];\ | |
| while ( !propValue.isNull() ) {\ | |
| string propertyName = propValue.get("name", "").asString();\ | |
| \ | |
| if ( propValue.isMember("int") ) {\ | |
| int val = propValue.get("int", 0).asInt();\ | |
| setCustomInt(item, propertyName, val);\ | |
| }\ | |
| if ( propValue.isMember("float") ) {\ | |
| float val = propValue.get("float", 0).asFloat();\ | |
| setCustomFloat(item, propertyName, val);\ | |
| }\ | |
| if ( propValue.isMember("string") ) {\ | |
| string val = propValue.get("string", 0).asString();\ | |
| setCustomString(item, propertyName, val);\ | |
| }\ | |
| if ( propValue.isMember("vec2") ) {\ | |
| b2Vec2 val = jsonToVec("vec2", propValue);\ | |
| setCustomVector(item, propertyName, val);\ | |
| }\ | |
| if ( propValue.isMember("bool") ) {\ | |
| bool val = propValue.get("bool", 0).asBool();\ | |
| setCustomBool(item, propertyName, val);\ | |
| }\ | |
| \ | |
| propValue = value["customProperties"][i++];\ | |
| }\ | |
| } | |
| IMPLEMENT_READ_CUSTOM_PROPERTIES_FROM_JSON(b2Body) | |
| IMPLEMENT_READ_CUSTOM_PROPERTIES_FROM_JSON(b2Fixture) | |
| IMPLEMENT_READ_CUSTOM_PROPERTIES_FROM_JSON(b2Joint) | |
| IMPLEMENT_READ_CUSTOM_PROPERTIES_FROM_JSON(b2dJsonImage) | |
| IMPLEMENT_READ_CUSTOM_PROPERTIES_FROM_JSON(b2World) | |
| ///////// | |
| void b2dJson::floatToJson(const char* name, float f, Json::Value& value) | |
| { | |
| //cut down on file space for common values | |
| if ( f == 0 ) | |
| value[name] = 0; | |
| else if ( f == 1 ) | |
| value[name] = 1; | |
| else { | |
| if ( m_useHumanReadableFloats ) | |
| value[name] = f; | |
| else | |
| value[name] = floatToHex(f); | |
| } | |
| } | |
| inline void b2dJson::vecToJson(const char* name, unsigned int v, Json::Value& value, int index) | |
| { | |
| if (index > -1) | |
| value[name][index] = v; | |
| else | |
| value[name] = v; | |
| } | |
| void b2dJson::vecToJson(const char *name, float v, Json::Value &value, int index) | |
| { | |
| if (index > -1) { | |
| if ( m_useHumanReadableFloats ) { | |
| value[name][index] = v; | |
| } | |
| else { | |
| if ( v == 0 ) | |
| value[name][index] = 0; | |
| else if ( v == 1 ) | |
| value[name][index] = 1; | |
| else | |
| value[name][index] = floatToHex(v); | |
| } | |
| } | |
| else | |
| floatToJson(name, v, value); | |
| } | |
| inline void b2dJson::vecToJson(const char* name, b2Vec2 vec, Json::Value& value, int index) | |
| { | |
| if (index > -1) { | |
| if ( m_useHumanReadableFloats ) { | |
| value[name]["x"][index] = vec.x; | |
| value[name]["y"][index] = vec.y; | |
| } | |
| else { | |
| if ( vec.x == 0 ) | |
| value[name]["x"][index] = 0; | |
| else if ( vec.x == 1 ) | |
| value[name]["x"][index] = 1; | |
| else | |
| value[name]["x"][index] = floatToHex(vec.x); | |
| if ( vec.y == 0 ) | |
| value[name]["y"][index] = 0; | |
| else if ( vec.y == 1 ) | |
| value[name]["y"][index] = 1; | |
| else | |
| value[name]["y"][index] = floatToHex(vec.y); | |
| } | |
| } | |
| else { | |
| if ( vec.x == 0 && vec.y == 0 ) | |
| value[name] = 0;//cut down on file space for common values | |
| else { | |
| floatToJson("x", vec.x, value[name]); | |
| floatToJson("y", vec.y, value[name]); | |
| } | |
| } | |
| } | |
| void b2dJson::clear() | |
| { | |
| m_indexToBodyMap.clear(); | |
| m_bodyToIndexMap.clear(); | |
| m_jointToIndexMap.clear(); | |
| m_bodies.clear(); | |
| m_joints.clear(); | |
| m_images.clear(); | |
| m_bodyToNameMap.clear(); | |
| m_fixtureToNameMap.clear(); | |
| m_jointToNameMap.clear(); | |
| m_imageToNameMap.clear(); | |
| } | |
| b2World *b2dJson::readFromValue(Json::Value worldValue) | |
| { | |
| clear(); | |
| return j2b2World(worldValue); | |
| } | |
| b2World* b2dJson::readFromString(std::string str, std::string& errorMsg) | |
| { | |
| Json::Value worldValue; | |
| Json::Reader reader; | |
| if ( ! reader.parse(str, worldValue) ) | |
| { | |
| //std::cout << "Failed to parse string\n" << reader.getFormattedErrorMessages(); | |
| errorMsg = string("Failed to parse JSON:\n") + reader.getFormatedErrorMessages(); | |
| return NULL; | |
| } | |
| return j2b2World(worldValue); | |
| } | |
| b2World* b2dJson::readFromFile(const char* filename, std::string& errorMsg) | |
| { | |
| if (!filename) | |
| return NULL; | |
| std::ifstream ifs; | |
| ifs.open(filename, std::ios::in); | |
| if (!ifs) { | |
| //std::cout << "Could not open file " << filename << " for reading\n"; | |
| errorMsg = string("Could not open file '") + string(filename) + string("' for reading"); | |
| return NULL; | |
| } | |
| Json::Value worldValue; | |
| Json::Reader reader; | |
| if ( ! reader.parse(ifs, worldValue) ) | |
| { | |
| //std::cout << "Failed to parse " << filename << std::endl << reader.getFormattedErrorMessages(); | |
| errorMsg = string("Failed to parse '") + string(filename) + string("' : ") + reader.getFormatedErrorMessages(); | |
| ifs.close(); | |
| return NULL; | |
| } | |
| ifs.close(); | |
| return j2b2World(worldValue); | |
| } | |
| b2World* b2dJson::j2b2World(Json::Value worldValue) | |
| { | |
| m_bodies.clear(); | |
| b2World* world = new b2World( jsonToVec("gravity", worldValue) ); | |
| world->SetAllowSleeping( worldValue["allowSleep"].asBool() ); | |
| world->SetAutoClearForces( worldValue["autoClearForces"].asBool() ); | |
| world->SetWarmStarting( worldValue["warmStarting"].asBool() ); | |
| world->SetContinuousPhysics( worldValue["continuousPhysics"].asBool() ); | |
| world->SetSubStepping( worldValue["subStepping"].asBool() ); | |
| readCustomPropertiesFromJson(world, worldValue); | |
| //bool recreationMayDiffer = false; //hahaha | |
| //if ( ! world->GetAutoClearForces() ) { std::cout << "Note: world is not set to auto clear forces.\n"; recreationMayDiffer = true; } | |
| //if ( world->GetWarmStarting() ) { std::cout << "Note: world is set to use warm starting.\n"; recreationMayDiffer = true; } | |
| //if ( world->GetContinuousPhysics() ) { std::cout << "Note: world is set to use continuous physics.\n"; recreationMayDiffer = true; } | |
| //if ( world->GetSubStepping() ) { std::cout << "Note: world is set to use sub stepping.\n"; recreationMayDiffer = true; } | |
| //if ( worldValue["hasDestructionListener"].asBool() ) { std::cout << "Note: world originally had a destruction listener set.\n"; recreationMayDiffer = true; } | |
| //if ( worldValue["hasContactFilter"].asBool() ) { std::cout << "Note: world originally had a contact filter set.\n"; recreationMayDiffer = true; } | |
| //if ( worldValue["hasContactListener"].asBool() ) { std::cout << "Note: world originally had a contact listener set.\n"; recreationMayDiffer = true; } | |
| //if ( recreationMayDiffer ) | |
| // std::cout << "Recreated behaviour may differ from original.\n"; | |
| int i = 0; | |
| Json::Value bodyValue = worldValue["body"][i]; | |
| while ( !bodyValue.isNull() ) { | |
| b2Body* body = j2b2Body(world, bodyValue); | |
| readCustomPropertiesFromJson(body, bodyValue); | |
| m_bodies.push_back(body); | |
| m_indexToBodyMap[i] = body; | |
| i++; | |
| bodyValue = worldValue["body"][i]; | |
| } | |
| //need two passes for joints because gear joints reference other joints | |
| i = 0; | |
| Json::Value jointValue = worldValue["joint"][i++]; | |
| while ( !jointValue.isNull() ) { | |
| if ( jointValue["type"].asString() != "gear" ) { | |
| b2Joint* joint = j2b2Joint(world, jointValue); | |
| readCustomPropertiesFromJson(joint, jointValue); | |
| m_joints.push_back(joint); | |
| } | |
| jointValue = worldValue["joint"][i++]; | |
| } | |
| i = 0; | |
| jointValue = worldValue["joint"][i++]; | |
| while ( !jointValue.isNull() ) { | |
| if ( jointValue["type"].asString() == "gear" ) { | |
| b2Joint* joint = j2b2Joint(world, jointValue); | |
| readCustomPropertiesFromJson(joint, jointValue); | |
| m_joints.push_back(joint); | |
| } | |
| jointValue = worldValue["joint"][i++]; | |
| } | |
| i = 0; | |
| Json::Value imageValue = worldValue["image"][i++]; | |
| while ( !imageValue.isNull() ) { | |
| b2dJsonImage* img = j2b2dJsonImage(imageValue); | |
| readCustomPropertiesFromJson(img, imageValue); | |
| m_images.push_back(img); | |
| addImage(img); | |
| imageValue = worldValue["image"][i++]; | |
| } | |
| return world; | |
| } | |
| b2Body* b2dJson::j2b2Body(b2World* world, Json::Value bodyValue) | |
| { | |
| b2Body* body = NULL; | |
| b2BodyDef bodyDef; | |
| bodyDef.type = (b2BodyType)bodyValue["type"].asInt(); | |
| bodyDef.position = jsonToVec("position", bodyValue); | |
| bodyDef.angle = jsonToFloat("angle", bodyValue ); | |
| bodyDef.linearVelocity = jsonToVec("linearVelocity", bodyValue); | |
| bodyDef.angularVelocity = jsonToFloat("angularVelocity", bodyValue); | |
| bodyDef.linearDamping = jsonToFloat("linearDamping", bodyValue, -1, 0); | |
| bodyDef.angularDamping = jsonToFloat("angularDamping", bodyValue, -1, 0); | |
| bodyDef.gravityScale = jsonToFloat("gravityScale", bodyValue, -1, 1); | |
| bodyDef.allowSleep = bodyValue.get("allowSleep",true).asBool(); | |
| bodyDef.awake = bodyValue.get("awake", false).asBool(); | |
| bodyDef.fixedRotation = bodyValue.get("fixedRotation",false).asBool(); | |
| bodyDef.bullet = bodyValue.get("bullet",false).asBool(); | |
| bodyDef.active = bodyValue.get("active",true).asBool(); | |
| body = world->CreateBody(&bodyDef); | |
| string bodyName = bodyValue.get("name","").asString(); | |
| if ( bodyName != "" ) { | |
| //printf("Found named body: %s\n",bodyName.c_str()); | |
| setBodyName(body, bodyName.c_str()); | |
| } | |
| int i = 0; | |
| Json::Value fixtureValue = bodyValue["fixture"][i++]; | |
| while ( !fixtureValue.isNull() ) { | |
| b2Fixture* fixture = j2b2Fixture(body, fixtureValue); | |
| readCustomPropertiesFromJson(fixture, fixtureValue); | |
| fixtureValue = bodyValue["fixture"][i++]; | |
| } | |
| //may be necessary if user has overridden mass characteristics | |
| b2MassData massData; | |
| massData.mass = jsonToFloat("massData-mass", bodyValue); | |
| massData.center = jsonToVec("massData-center", bodyValue); | |
| massData.I = jsonToFloat("massData-I", bodyValue); | |
| body->SetMassData(&massData); | |
| return body; | |
| } | |
| b2Fixture* b2dJson::j2b2Fixture(b2Body* body, Json::Value fixtureValue) | |
| { | |
| b2Fixture* fixture = NULL; | |
| b2FixtureDef fixtureDef; | |
| fixtureDef.restitution = jsonToFloat("restitution", fixtureValue); | |
| fixtureDef.friction = jsonToFloat("friction", fixtureValue); | |
| fixtureDef.density = jsonToFloat("density", fixtureValue); | |
| fixtureDef.isSensor = fixtureValue.get("sensor",false).asBool(); | |
| fixtureDef.filter.categoryBits = fixtureValue.get("filter-categoryBits",0x0001).asInt(); | |
| fixtureDef.filter.maskBits = fixtureValue.get("filter-maskBits",0xffff).asInt(); | |
| fixtureDef.filter.groupIndex = fixtureValue.get("filter-groupIndex",0).asInt(); | |
| if ( fixtureValue.isNull() ) | |
| return NULL; | |
| if ( !fixtureValue["circle"].isNull() ) { | |
| b2CircleShape circleShape; | |
| circleShape.m_radius = jsonToFloat("radius", fixtureValue["circle"]); | |
| circleShape.m_p = jsonToVec("center", fixtureValue["circle"]); | |
| fixtureDef.shape = &circleShape; | |
| fixture = body->CreateFixture(&fixtureDef); | |
| } | |
| else if ( !fixtureValue["edge"].isNull() ) { | |
| b2EdgeShape edgeShape; | |
| edgeShape.m_vertex1 = jsonToVec("vertex1", fixtureValue["edge"]); | |
| edgeShape.m_vertex2 = jsonToVec("vertex2", fixtureValue["edge"]); | |
| edgeShape.m_hasVertex0 = fixtureValue["edge"].get("hasVertex0",false).asBool(); | |
| edgeShape.m_hasVertex3 = fixtureValue["edge"].get("hasVertex3",false).asBool(); | |
| if ( edgeShape.m_hasVertex0 ) | |
| edgeShape.m_vertex0 = jsonToVec("vertex0", fixtureValue["edge"]); | |
| if ( edgeShape.m_hasVertex3 ) | |
| edgeShape.m_vertex3 = jsonToVec("vertex3", fixtureValue["edge"]); | |
| fixtureDef.shape = &edgeShape; | |
| fixture = body->CreateFixture(&fixtureDef); | |
| } | |
| else if ( !fixtureValue["loop"].isNull() ) { //support old format (r197) | |
| b2ChainShape chainShape; | |
| int numVertices = fixtureValue["loop"]["vertices"]["x"].size(); | |
| b2Vec2* vertices = new b2Vec2[numVertices]; | |
| for (int i = 0; i < numVertices; i++) | |
| vertices[i] = jsonToVec("vertices", fixtureValue["loop"], i); | |
| chainShape.CreateLoop(vertices, numVertices); | |
| fixtureDef.shape = &chainShape; | |
| fixture = body->CreateFixture(&fixtureDef); | |
| delete[] vertices; | |
| } | |
| else if ( !fixtureValue["chain"].isNull() ) { | |
| b2ChainShape chainShape; | |
| int numVertices = fixtureValue["chain"]["vertices"]["x"].size(); | |
| b2Vec2* vertices = new b2Vec2[numVertices]; | |
| for (int i = 0; i < numVertices; i++) | |
| vertices[i] = jsonToVec("vertices", fixtureValue["chain"], i); | |
| chainShape.CreateChain(vertices, numVertices); | |
| chainShape.m_hasPrevVertex = fixtureValue["chain"].get("hasPrevVertex",false).asBool(); | |
| chainShape.m_hasNextVertex = fixtureValue["chain"].get("hasNextVertex",false).asBool(); | |
| if ( chainShape.m_hasPrevVertex ) | |
| chainShape.m_prevVertex = jsonToVec("prevVertex", fixtureValue["chain"]); | |
| if ( chainShape.m_hasNextVertex ) | |
| chainShape.m_nextVertex = jsonToVec("nextVertex", fixtureValue["chain"]); | |
| fixtureDef.shape = &chainShape; | |
| fixture = body->CreateFixture(&fixtureDef); | |
| delete[] vertices; | |
| } | |
| else if ( !fixtureValue["polygon"].isNull() ) { | |
| b2Vec2 vertices[b2_maxPolygonVertices]; | |
| int numVertices = fixtureValue["polygon"]["vertices"]["x"].size(); | |
| if ( numVertices > b2_maxPolygonVertices ) { | |
| std::cout << "Ignoring polygon fixture with too many vertices.\n"; | |
| } | |
| else if ( numVertices < 2 ) { | |
| std::cout << "Ignoring polygon fixture less than two vertices.\n"; | |
| } | |
| else if ( numVertices == 2 ) { | |
| std::cout << "Creating edge shape instead of polygon with two vertices.\n"; | |
| b2EdgeShape edgeShape; | |
| edgeShape.m_vertex1 = jsonToVec("vertices", fixtureValue["polygon"], 0); | |
| edgeShape.m_vertex2 = jsonToVec("vertices", fixtureValue["polygon"], 1); | |
| fixtureDef.shape = &edgeShape; | |
| fixture = body->CreateFixture(&fixtureDef); | |
| } | |
| else { | |
| b2PolygonShape polygonShape; | |
| for (int i = 0; i < numVertices; i++) | |
| vertices[i] = jsonToVec("vertices", fixtureValue["polygon"], i); | |
| polygonShape.Set(vertices, numVertices); | |
| fixtureDef.shape = &polygonShape; | |
| fixture = body->CreateFixture(&fixtureDef); | |
| } | |
| } | |
| string fixtureName = fixtureValue.get("name","").asString(); | |
| if ( fixtureName != "" ) { | |
| setFixtureName(fixture, fixtureName.c_str()); | |
| } | |
| return fixture; | |
| } | |
| b2Joint* b2dJson::j2b2Joint(b2World* world, Json::Value jointValue) | |
| { | |
| b2Joint* joint = NULL; | |
| int bodyIndexA = jointValue["bodyA"].asInt(); | |
| int bodyIndexB = jointValue["bodyB"].asInt(); | |
| if ( bodyIndexA >= (int)m_bodies.size() || bodyIndexB >= (int)m_bodies.size() ) | |
| return NULL; | |
| //keep these in scope after the if/else below | |
| b2RevoluteJointDef revoluteDef; | |
| b2PrismaticJointDef prismaticDef; | |
| b2DistanceJointDef distanceDef; | |
| b2PulleyJointDef pulleyDef; | |
| b2MouseJointDef mouseDef; | |
| b2GearJointDef gearDef; | |
| b2WheelJointDef wheelDef; | |
| //b2MotorJointDef motorDef; | |
| b2WeldJointDef weldDef; | |
| b2FrictionJointDef frictionDef; | |
| b2RopeJointDef ropeDef; | |
| //will be used to select one of the above to work with | |
| b2JointDef* jointDef = NULL; | |
| b2Vec2 mouseJointTarget; | |
| std::string type = jointValue["type"].asString(); | |
| if ( type == "revolute" ) | |
| { | |
| jointDef = &revoluteDef; | |
| revoluteDef.localAnchorA = jsonToVec("anchorA", jointValue); | |
| revoluteDef.localAnchorB = jsonToVec("anchorB", jointValue); | |
| revoluteDef.referenceAngle = jsonToFloat("refAngle", jointValue); | |
| revoluteDef.enableLimit = jointValue["enableLimit"].asBool(); | |
| revoluteDef.lowerAngle = jsonToFloat("lowerLimit", jointValue); | |
| revoluteDef.upperAngle = jsonToFloat("upperLimit", jointValue); | |
| revoluteDef.enableMotor = jointValue["enableMotor"].asBool(); | |
| revoluteDef.motorSpeed = jsonToFloat("motorSpeed", jointValue); | |
| revoluteDef.maxMotorTorque = jsonToFloat("maxMotorTorque", jointValue); | |
| } | |
| else if ( type == "prismatic" ) | |
| { | |
| jointDef = &prismaticDef; | |
| prismaticDef.localAnchorA = jsonToVec("anchorA", jointValue); | |
| prismaticDef.localAnchorB = jsonToVec("anchorB", jointValue); | |
| if ( !jointValue["localAxisA"].isNull() ) | |
| prismaticDef.localAxisA = jsonToVec("localAxisA", jointValue); | |
| else | |
| prismaticDef.localAxisA = jsonToVec("localAxis1", jointValue); | |
| prismaticDef.referenceAngle = jsonToFloat("refAngle", jointValue); | |
| prismaticDef.enableLimit = jointValue["enableLimit"].asBool(); | |
| prismaticDef.lowerTranslation = jsonToFloat("lowerLimit", jointValue); | |
| prismaticDef.upperTranslation = jsonToFloat("upperLimit", jointValue); | |
| prismaticDef.enableMotor = jointValue["enableMotor"].asBool(); | |
| prismaticDef.motorSpeed = jsonToFloat("motorSpeed", jointValue); | |
| prismaticDef.maxMotorForce = jsonToFloat("maxMotorForce", jointValue); | |
| } | |
| else if ( type == "distance" ) | |
| { | |
| jointDef = &distanceDef; | |
| distanceDef.localAnchorA = jsonToVec("anchorA", jointValue); | |
| distanceDef.localAnchorB = jsonToVec("anchorB", jointValue); | |
| distanceDef.length = jsonToFloat("length", jointValue); | |
| distanceDef.frequencyHz = jsonToFloat("frequency", jointValue); | |
| distanceDef.dampingRatio = jsonToFloat("dampingRatio", jointValue); | |
| } | |
| else if ( type == "pulley" ) | |
| { | |
| jointDef = &pulleyDef; | |
| pulleyDef.groundAnchorA = jsonToVec("groundAnchorA", jointValue); | |
| pulleyDef.groundAnchorB = jsonToVec("groundAnchorB", jointValue); | |
| pulleyDef.localAnchorA = jsonToVec("anchorA", jointValue); | |
| pulleyDef.localAnchorB = jsonToVec("anchorB", jointValue); | |
| pulleyDef.lengthA = jsonToFloat("lengthA", jointValue); | |
| pulleyDef.lengthB = jsonToFloat("lengthB", jointValue); | |
| pulleyDef.ratio = jsonToFloat("ratio", jointValue); | |
| } | |
| else if ( type == "mouse" ) | |
| { | |
| jointDef = &mouseDef; | |
| mouseJointTarget = jsonToVec("target", jointValue); | |
| mouseDef.target = jsonToVec("anchorB", jointValue);//alter after creating joint | |
| mouseDef.maxForce = jsonToFloat("maxForce", jointValue); | |
| mouseDef.frequencyHz = jsonToFloat("frequency", jointValue); | |
| mouseDef.dampingRatio = jsonToFloat("dampingRatio", jointValue); | |
| } | |
| else if ( type == "gear" ) | |
| { | |
| jointDef = &gearDef; | |
| int jointIndex1 = jointValue["joint1"].asInt(); | |
| int jointIndex2 = jointValue["joint2"].asInt(); | |
| gearDef.joint1 = m_joints[jointIndex1]; | |
| gearDef.joint2 = m_joints[jointIndex2]; | |
| gearDef.ratio = jsonToFloat("ratio", jointValue); | |
| } | |
| else if ( type == "wheel" ) | |
| { | |
| jointDef = &wheelDef; | |
| wheelDef.localAnchorA = jsonToVec("anchorA", jointValue); | |
| wheelDef.localAnchorB = jsonToVec("anchorB", jointValue); | |
| wheelDef.localAxisA = jsonToVec("localAxisA", jointValue); | |
| wheelDef.enableMotor = jointValue["enableMotor"].asBool(); | |
| wheelDef.motorSpeed = jsonToFloat("motorSpeed", jointValue); | |
| wheelDef.maxMotorTorque = jsonToFloat("maxMotorTorque", jointValue); | |
| wheelDef.frequencyHz = jsonToFloat("springFrequency", jointValue); | |
| wheelDef.dampingRatio = jsonToFloat("springDampingRatio", jointValue); | |
| } | |
| //else if ( type == "motor" ) | |
| //{ | |
| // jointDef = &motorDef; | |
| // motorDef.linearOffset = jsonToVec("anchorA", jointValue);//editor uses anchorA as the linear offset | |
| // motorDef.angularOffset = jsonToFloat("refAngle", jointValue); | |
| // motorDef.maxForce = jsonToFloat("maxForce", jointValue); | |
| // motorDef.maxTorque = jsonToFloat("maxTorque", jointValue); | |
| // motorDef.correctionFactor = jsonToFloat("correctionFactor", jointValue); | |
| //} | |
| else if ( type == "weld" ) | |
| { | |
| jointDef = &weldDef; | |
| weldDef.localAnchorA = jsonToVec("anchorA", jointValue); | |
| weldDef.localAnchorB = jsonToVec("anchorB", jointValue); | |
| weldDef.referenceAngle = jsonToFloat("refAngle", jointValue); | |
| weldDef.frequencyHz = jsonToFloat("frequency", jointValue); | |
| weldDef.dampingRatio = jsonToFloat("dampingRatio", jointValue); | |
| } | |
| else if ( type == "friction" ) | |
| { | |
| jointDef = &frictionDef; | |
| frictionDef.localAnchorA = jsonToVec("anchorA", jointValue); | |
| frictionDef.localAnchorB = jsonToVec("anchorB", jointValue); | |
| frictionDef.maxForce = jsonToFloat("maxForce", jointValue); | |
| frictionDef.maxTorque = jsonToFloat("maxTorque", jointValue); | |
| } | |
| else if ( type == "rope" ) | |
| { | |
| jointDef = &ropeDef; | |
| ropeDef.localAnchorA = jsonToVec("anchorA", jointValue); | |
| ropeDef.localAnchorB = jsonToVec("anchorB", jointValue); | |
| ropeDef.maxLength = jsonToFloat("maxLength", jointValue); | |
| } | |
| if ( jointDef ) { | |
| //set features common to all joints | |
| jointDef->bodyA = m_bodies[bodyIndexA]; | |
| jointDef->bodyB = m_bodies[bodyIndexB]; | |
| jointDef->collideConnected = jointValue.get("collideConnected",false).asBool(); | |
| joint = world->CreateJoint(jointDef); | |
| if ( type == "mouse" ) | |
| ((b2MouseJoint*)joint)->SetTarget(mouseJointTarget); | |
| string jointName = jointValue.get("name","").asString(); | |
| if ( jointName != "" ) { | |
| setJointName(joint, jointName.c_str()); | |
| } | |
| } | |
| return joint; | |
| } | |
| b2dJsonImage* b2dJson::j2b2dJsonImage(Json::Value imageValue) | |
| { | |
| b2dJsonImage* img = new b2dJsonImage(); | |
| if ( imageValue["body"].isInt() ) | |
| img->body = lookupBodyFromIndex( imageValue["body"].asInt() ); | |
| if ( imageValue["name"].isString() ) { | |
| img->name = imageValue["name"].asString(); | |
| setImageName(img, img->name.c_str()); | |
| } | |
| if ( imageValue["file"].isString() ) | |
| img->file = imageValue["file"].asString(); | |
| img->center = jsonToVec("center", imageValue); | |
| img->angle = jsonToFloat("angle", imageValue); | |
| img->scale = jsonToFloat("scale", imageValue); | |
| img->opacity = jsonToFloat("opacity", imageValue); | |
| img->renderOrder = jsonToFloat("renderOrder", imageValue); | |
| if ( imageValue.isMember("colorTint") ) { | |
| for (int i = 0; i < 4; i++) { | |
| if ( imageValue["colorTint"][i].isInt() ) | |
| img->colorTint[i] = imageValue["colorTint"][i].asInt(); | |
| } | |
| } | |
| if ( imageValue["flip"].isBool() ) | |
| img->flip = imageValue["flip"].asBool(); | |
| if ( imageValue["filter"].isInt() ) | |
| img->filter = imageValue["filter"].asInt(); | |
| for (int i = 0; i < 4; i++) | |
| img->corners[i] = jsonToVec("corners", imageValue, i); | |
| if ( imageValue["glVertexPointer"].isArray() && imageValue["glTexCoordPointer"].isArray() && | |
| (imageValue["glVertexPointer"].size() == imageValue["glTexCoordPointer"].size()) ) { | |
| int numFloats = imageValue["glVertexPointer"].size(); | |
| img->numPoints = numFloats / 2; | |
| img->points = new float[numFloats]; | |
| img->uvCoords = new float[numFloats]; | |
| for (int i = 0; i < numFloats; i++) { | |
| img->points[i] = jsonToFloat("glVertexPointer", imageValue, i); | |
| img->uvCoords[i] = jsonToFloat("glTexCoordPointer", imageValue, i); | |
| } | |
| } | |
| if ( imageValue["glDrawElements"].isArray() ) { | |
| img->numIndices = imageValue["glDrawElements"].size(); | |
| img->indices = new unsigned short[img->numIndices]; | |
| for (int i = 0; i < img->numIndices; i++) | |
| img->indices[i] = imageValue["glDrawElements"][i].asInt(); | |
| } | |
| sysLog.Log("Checking for file....."); | |
| sysLog.Log("In b2dJsonImage* b2dJson::j2b2dJsonImage(Json::Value imageValue)"); | |
| if(!img->fileExists(&img->file)) | |
| { | |
| sysLog.Log(img->file+" = File does not exist"); | |
| } | |
| return img; | |
| } | |
| float b2dJson::jsonToFloat(const char* name, Json::Value& value, int index, float defaultValue) | |
| { | |
| if ( ! value.isMember(name) ) | |
| return defaultValue; | |
| if ( index > -1 ) { | |
| if ( value[name][index].isNull() ) | |
| return defaultValue; | |
| else if ( value[name][index].isInt() ) | |
| return value[name][index].asInt();//usually 0 or 1 | |
| else if ( value[name][index].isString() ) | |
| return hexToFloat( value[name][index].asString() ); | |
| else | |
| return value[name][index].asFloat(); | |
| } | |
| else { | |
| if ( value[name].isNull() ) | |
| return defaultValue; | |
| else if ( value[name].isInt() ) | |
| return value[name].asInt();//usually 0 or 1 | |
| else if ( value[name].isString() ) | |
| return hexToFloat( value[name].asString() ); | |
| else | |
| return value[name].asFloat(); | |
| } | |
| } | |
| b2Vec2 b2dJson::jsonToVec(const char* name, Json::Value& value, int index, b2Vec2 defaultValue) | |
| { | |
| b2Vec2 vec = defaultValue; | |
| if ( ! value.isMember(name) ) | |
| return defaultValue; | |
| if (index > -1) { | |
| if ( value[name]["x"][index].isInt() ) //usually 0 or 1 | |
| vec.x = value[name]["x"][index].asInt(); | |
| else if ( value[name]["x"][index].isString() ) | |
| vec.x = hexToFloat(value[name]["x"][index].asString()); | |
| else | |
| vec.x = value[name]["x"][index].asFloat(); | |
| if ( value[name]["y"][index].isInt() ) //usually 0 or 1 | |
| vec.y = value[name]["y"][index].asInt(); | |
| else if ( value[name]["y"][index].isString() ) | |
| vec.y = hexToFloat(value[name]["y"][index].asString()); | |
| else | |
| vec.y = value[name]["y"][index].asFloat(); | |
| } | |
| else { | |
| if ( value[name].isInt() ) //zero vector | |
| vec.Set(0,0); | |
| else { | |
| vec.x = jsonToFloat("x", value[name]); | |
| vec.y = jsonToFloat("y", value[name]); | |
| } | |
| } | |
| return vec; | |
| } | |
| std::string b2dJson::floatToHex(float f) | |
| { | |
| char buf[16]; | |
| //sprintf(buf, "%08X", *((int*)(&f)) ); dereferencing type-punned pointer will break strict-aliasing rules | |
| int* i = (int*)(&f); | |
| sprintf(buf, "%08X", *i ); | |
| return std::string(buf); | |
| } | |
| float b2dJson::hexToFloat(std::string str) | |
| { | |
| int strLen = 8;//32 bit float | |
| unsigned char bytes[4]; | |
| int bptr = (strLen / 2) - 1; | |
| for (int i = 0; i < strLen; i++){ | |
| unsigned char c; | |
| c = str[i]; | |
| if (c > '9') c -= 7; | |
| c <<= 4; | |
| bytes[bptr] = c; | |
| ++i; | |
| c = str[i]; | |
| if (c > '9') c -= 7; | |
| c -= '0'; | |
| bytes[bptr] |= c; | |
| --bptr; | |
| } | |
| //return *((float*)bytes); dereferencing type-punned pointer will break strict-aliasing rules | |
| float* f = (float*)bytes; | |
| return *f; | |
| } | |
| b2Body* b2dJson::lookupBodyFromIndex( unsigned int index ) | |
| { | |
| std::map<int,b2Body*>::iterator it = m_indexToBodyMap.find(index); | |
| if ( it != m_indexToBodyMap.end() ) | |
| return it->second; | |
| else | |
| return NULL; | |
| } | |
| int b2dJson::lookupBodyIndex( b2Body* body ) | |
| { | |
| std::map<b2Body*,int>::iterator it = m_bodyToIndexMap.find(body); | |
| if ( it != m_bodyToIndexMap.end() ) | |
| return it->second; | |
| else | |
| return -1; | |
| } | |
| int b2dJson::lookupJointIndex( b2Joint* joint ) | |
| { | |
| std::map<b2Joint*,int>::iterator it = m_jointToIndexMap.find(joint); | |
| if ( it != m_jointToIndexMap.end() ) | |
| return it->second; | |
| else | |
| return -1; | |
| } | |
| string b2dJson::getBodyName(b2Body* body) | |
| { | |
| map<b2Body*,string>::iterator it = m_bodyToNameMap.find( body ); | |
| if ( it == m_bodyToNameMap.end() ) | |
| return ""; | |
| return it->second; | |
| } | |
| string b2dJson::getFixtureName(b2Fixture* fixture) | |
| { | |
| map<b2Fixture*,string>::iterator it = m_fixtureToNameMap.find( fixture ); | |
| if ( it == m_fixtureToNameMap.end() ) | |
| return ""; | |
| return it->second; | |
| } | |
| string b2dJson::getJointName(b2Joint* joint) | |
| { | |
| map<b2Joint*,string>::iterator it = m_jointToNameMap.find( joint ); | |
| if ( it == m_jointToNameMap.end() ) | |
| return ""; | |
| return it->second; | |
| } | |
| string b2dJson::getImageName(b2dJsonImage *img) | |
| { | |
| map<b2dJsonImage*,string>::iterator it = m_imageToNameMap.find( img ); | |
| if ( it == m_imageToNameMap.end() ) | |
| return ""; | |
| return it->second; | |
| } | |
| int b2dJson::getBodiesByName(string name, vector<b2Body*>& bodies) | |
| { | |
| map<b2Body*,string>::iterator it = m_bodyToNameMap.begin(); | |
| map<b2Body*,string>::iterator end = m_bodyToNameMap.end(); | |
| while (it != end) { | |
| if ( it->second == name ) | |
| bodies.push_back(it->first); | |
| ++it; | |
| } | |
| return bodies.size(); | |
| } | |
| int b2dJson::getFixturesByName(string name, vector<b2Fixture*>& fixtures) | |
| { | |
| map<b2Fixture*,string>::iterator it = m_fixtureToNameMap.begin(); | |
| map<b2Fixture*,string>::iterator end = m_fixtureToNameMap.end(); | |
| while (it != end) { | |
| if ( it->second == name ) | |
| fixtures.push_back(it->first); | |
| ++it; | |
| } | |
| return fixtures.size(); | |
| } | |
| int b2dJson::getJointsByName(string name, vector<b2Joint*>& joints) | |
| { | |
| map<b2Joint*,string>::iterator it = m_jointToNameMap.begin(); | |
| map<b2Joint*,string>::iterator end = m_jointToNameMap.end(); | |
| while (it != end) { | |
| if ( it->second == name ) | |
| joints.push_back(it->first); | |
| ++it; | |
| } | |
| return joints.size(); | |
| } | |
| int b2dJson::getImagesByName(string name, vector<b2dJsonImage*> &images) | |
| { | |
| map<b2dJsonImage*,string>::iterator it = m_imageToNameMap.begin(); | |
| map<b2dJsonImage*,string>::iterator end = m_imageToNameMap.end(); | |
| while (it != end) { | |
| if ( it->second == name ) | |
| images.push_back(it->first); | |
| ++it; | |
| } | |
| return images.size(); | |
| } | |
| int b2dJson::getAllImages(vector<b2dJsonImage*> &images) | |
| { | |
| images.insert( images.begin(), m_images.begin(), m_images.end() ); | |
| std::sort(images.begin(), images.end(), b2dJsonImage_renderOrder_ascending); | |
| return images.size(); | |
| } | |
| b2Body* b2dJson::getBodyByName(string name) | |
| { | |
| map<b2Body*,string>::iterator it = m_bodyToNameMap.begin(); | |
| map<b2Body*,string>::iterator end = m_bodyToNameMap.end(); | |
| while (it != end) { | |
| if ( it->second == name ) | |
| return it->first; | |
| ++it; | |
| } | |
| return NULL; | |
| } | |
| b2Fixture* b2dJson::getFixtureByName(string name) | |
| { | |
| map<b2Fixture*,string>::iterator it = m_fixtureToNameMap.begin(); | |
| map<b2Fixture*,string>::iterator end = m_fixtureToNameMap.end(); | |
| while (it != end) { | |
| if ( it->second == name ) | |
| return it->first; | |
| ++it; | |
| } | |
| return NULL; | |
| } | |
| b2Joint* b2dJson::getJointByName(string name) | |
| { | |
| map<b2Joint*,string>::iterator it = m_jointToNameMap.begin(); | |
| map<b2Joint*,string>::iterator end = m_jointToNameMap.end(); | |
| while (it != end) { | |
| if ( it->second == name ) | |
| return it->first; | |
| ++it; | |
| } | |
| return NULL; | |
| } | |
| b2dJsonImage* b2dJson::getImageByName(string name) | |
| { | |
| map<b2dJsonImage*,string>::iterator it = m_imageToNameMap.begin(); | |
| map<b2dJsonImage*,string>::iterator end = m_imageToNameMap.end(); | |
| while (it != end) { | |
| if ( it->second == name ) | |
| return it->first; | |
| ++it; | |
| } | |
| return NULL; | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "PhysicsEdgeActor.h" | |
| PhysicsEdgeActor::PhysicsEdgeActor(void) | |
| { | |
| this->_shapeType = SHAPETYPE_EDGE; | |
| this->_edge = b2EdgeShape(); | |
| PhysicsActor::SetShapeType(SHAPETYPE_EDGE); | |
| } | |
| PhysicsEdgeActor::~PhysicsEdgeActor(void) | |
| { | |
| if( _physBody != NULL ) | |
| { | |
| _physBody->SetUserData(NULL); | |
| theWorld.GetPhysicsWorld().DestroyBody(_physBody); | |
| } | |
| } | |
| void PhysicsEdgeActor::Set(b2Vec2 v1, b2Vec2 v2) | |
| { | |
| _edge.Set(v1, v2); | |
| } | |
| void PhysicsEdgeActor::Set(b2EdgeShape edge) | |
| { | |
| this->_edge = edge; | |
| } | |
| b2EdgeShape PhysicsEdgeActor::GetB2EdgeShape() | |
| { | |
| return this->_edge; | |
| } | |
| void PhysicsActor::InitPhysics() | |
| { | |
| //todo:add specific init logic for additional shapes (see eShapeType for shapes) | |
| if (!theWorld.IsPhysicsSetUp()) | |
| { | |
| sysLog.Log("ERROR: World physics must be initialized before Actor's."); | |
| return; | |
| } | |
| this->_shapeType = SHAPETYPE_EDGE; | |
| b2Shape* shape = NULL; | |
| b2FixtureDef fixtureDef; | |
| fixtureDef.shape = shape; | |
| fixtureDef.density = _density; | |
| fixtureDef.friction = _friction; | |
| fixtureDef.restitution = _restitution; | |
| fixtureDef.filter.groupIndex = _groupIndex; | |
| fixtureDef.isSensor = _isSensor; | |
| InitShape( shape ); | |
| b2BodyDef bd; | |
| bd.userData = this; | |
| bd.position.Set(_position.X, _position.Y); | |
| bd.angle = MathUtil::ToRadians(_rotation); | |
| bd.fixedRotation = _fixedRotation; | |
| if (MathUtil::FuzzyEquals(_density, 0.0f)) | |
| { | |
| bd.type = b2_staticBody; | |
| } | |
| else | |
| { | |
| bd.type = b2_dynamicBody; | |
| } | |
| _physBody = theWorld.GetPhysicsWorld().CreateBody(&bd); | |
| _physBody->CreateFixture(&fixtureDef); | |
| _physBody->SetUserData(this); | |
| CustomInitPhysics(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include "../Actors/PhysicsActor.h" | |
| #include "../Infrastructure/World.h" | |
| #include "../Infrastructure/Log.h" | |
| #include "../Util/MathUtil.h" | |
| #include <Box2D/Box2D.h> | |
| struct b2ShapeDef; | |
| class PhysicsEdgeActor:public PhysicsActor | |
| { | |
| public: | |
| PhysicsEdgeActor(void); | |
| void InitPhysics(); | |
| virtual void CustomInitPhysics(); | |
| virtual const String GetClassName() const { return "PhysicsEdgeActor"; } | |
| b2Vec2 GetVertexAt(int index); | |
| void SetVertexAt(int index, ); | |
| b2Vec2 GetFirstVertex(); | |
| b2Vec2 GetLastVertex(); | |
| void Set(b2Vec2 start, b2Vec2 end); | |
| void Set(b2EdgeShape edge); | |
| b2EdgeShape GetB2EdgeShape(); | |
| ~PhysicsEdgeActor(void); | |
| private: | |
| friend class World; | |
| b2EdgeShape _edge; | |
| void _syncPosRot(float x, float y, float rotation); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment