void TileMapLayer2D::SetObjectGroup(const TmxObjectGroup2D* objectGroup) { objectGroup_ = objectGroup; TmxFile2D* tmxFile = objectGroup->GetTmxFile(); nodes_.Resize(objectGroup->GetNumObjects()); for (unsigned i = 0; i < objectGroup->GetNumObjects(); ++i) { const TileMapObject2D* object = objectGroup->GetObject(i); // Create dummy node for all object SharedPtr<Node> objectNode(GetNode()->CreateTemporaryChild("Object")); objectNode->SetPosition(object->GetPosition()); // If object is tile, create static sprite component if (object->GetObjectType() == OT_TILE && object->GetTileGid() && object->GetTileSprite()) { StaticSprite2D* staticSprite = objectNode->CreateComponent<StaticSprite2D>(); staticSprite->SetSprite(object->GetTileSprite()); staticSprite->SetLayer(drawOrder_); staticSprite->SetOrderInLayer((int)((10.0f - object->GetPosition().y_) * 100)); if (tmxFile->GetInfo().orientation_ == O_ISOMETRIC) { staticSprite->SetUseHotSpot(true); staticSprite->SetHotSpot(Vector2(0.5f, 0.0f)); } } nodes_[i] = objectNode; } }
void TileMapLayer2D::SetTileLayer(const TmxTileLayer2D* tileLayer) { tileLayer_ = tileLayer; int width = tileLayer->GetWidth(); int height = tileLayer->GetHeight(); nodes_.Resize((unsigned)(width * height)); const TileMapInfo2D& info = tileMap_->GetInfo(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { const Tile2D* tile = tileLayer->GetTile(x, y); if (!tile) continue; SharedPtr<Node> tileNode(GetNode()->CreateTemporaryChild("Tile")); tileNode->SetPosition(info.TileIndexToPosition(x, y)); StaticSprite2D* staticSprite = tileNode->CreateComponent<StaticSprite2D>(); staticSprite->SetSprite(tile->GetSprite()); staticSprite->SetLayer(drawOrder_); staticSprite->SetOrderInLayer(y * width + x); nodes_[y * width + x] = tileNode; } } }
void TileMapLayer2D::SetTileLayer(const TmxTileLayer2D* tileLayer) { tileLayer_ = tileLayer; int width = tileLayer->GetWidth(); int height = tileLayer->GetHeight(); nodes_.Resize((unsigned)(width * height)); const TileMapInfo2D& info = tileMap_->GetInfo(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { const Tile2D* tile = tileLayer->GetTile(x, y); if (!tile) continue; SharedPtr<Node> tileNode(GetNode()->CreateChild("Tile")); tileNode->SetTemporary(true); tileNode->SetPosition(info.TileIndexToPosition(x, y)); StaticSprite2D* staticSprite = tileNode->CreateComponent<StaticSprite2D>(); staticSprite->SetSprite(tile->GetSprite()); staticSprite->SetLayer(drawOrder_); staticSprite->SetOrderInLayer(y * width + x); // ATOMIC BEGIN // collision RigidBody2D *body = NULL; TmxObjectGroup2D* group = tile->GetObjectGroup(); if (group) { for (unsigned i = 0; i < group->GetNumObjects(); i++) { TileMapObject2D* o = group->GetObject(i); if (o->ValidCollisionShape()) { if (!body) { body = tileNode->CreateComponent<RigidBody2D>(); body->SetBodyType(BT_STATIC); } o->CreateCollisionShape(tileNode); } } } // ATOMIC END nodes_[y * width + x] = tileNode; } } }
void TileMapLayer2D::SetImageLayer(const TmxImageLayer2D* imageLayer) { imageLayer_ = imageLayer; if (!imageLayer->GetSprite()) return; SharedPtr<Node> imageNode(GetNode()->CreateTemporaryChild("Tile")); imageNode->SetPosition(imageLayer->GetPosition()); StaticSprite2D* staticSprite = imageNode->CreateComponent<StaticSprite2D>(); staticSprite->SetSprite(imageLayer->GetSprite()); staticSprite->SetOrderInLayer(0); nodes_.Push(imageNode); }
void AnimatedSprite2D::UpdateAnimation(float timeStep) { if (!animation_) return; currentTime_ += timeStep * speed_; float time; float animtationLength = animation_->GetLength(); if (looped_) { time = fmodf(currentTime_, animtationLength); if (time < 0.0f) time += animation_->GetLength(); } else time = Clamp(currentTime_, 0.0f, animtationLength); for (unsigned i = 0; i < numTracks_; ++i) { trackNodeInfos_[i].worldSpace = false; const AnimationTrack2D& track = animation_->GetTrack(i); const Vector<AnimationKeyFrame2D>& keyFrames = track.keyFrames_; // Time out of range if (time < keyFrames[0].time_ || time > keyFrames.Back().time_) trackNodeInfos_[i].value.enabled_ = false; else { unsigned index = keyFrames.Size() - 1; for (unsigned j = 0; j < keyFrames.Size() - 1; ++j) { if (time <= keyFrames[j + 1].time_) { index = j; break; } } const AnimationKeyFrame2D& currKey = keyFrames[index]; AnimationKeyFrame2D& value = trackNodeInfos_[i].value; value.enabled_ = currKey.enabled_; value.parent_ = currKey.parent_; if (index < keyFrames.Size() - 1) { const AnimationKeyFrame2D& nextKey = keyFrames[index + 1]; float t = (time - currKey.time_) / (nextKey.time_ - currKey.time_); value.transform_ = currKey.transform_.Lerp(nextKey.transform_, t, currKey.spin_); if (trackNodeInfos_[i].hasSprite) value.alpha_ = Urho3D::Lerp(currKey.alpha_, nextKey.alpha_, t); } else { value.transform_ = currKey.transform_; if (trackNodeInfos_[i].hasSprite) value.alpha_ = currKey.alpha_; } if (trackNodeInfos_[i].hasSprite) { value.zIndex_ = currKey.zIndex_; value.sprite_ = currKey.sprite_; value.useHotSpot_ = currKey.useHotSpot_; value.hotSpot_ = currKey.hotSpot_; } } } for (unsigned i = 0; i < numTracks_; ++i) { Node* node = trackNodes_[i]; TrackNodeInfo& nodeInfo = trackNodeInfos_[i]; if (!nodeInfo.value.enabled_) node->SetEnabled(false); else { node->SetEnabled(true); // Calculate world transform. CalculateTimelineWorldTransform(i); // Update node's transform Vector2 position = nodeInfo.value.transform_.position_ * PIXEL_SIZE; if (flipX_) position.x_ = -position.x_; if (flipY_) position.y_ = -position.y_; node->SetPosition(position); float angle = nodeInfo.value.transform_.angle_; if (flipX_ != flipY_) angle = -angle; node->SetRotation(angle); node->SetScale(nodeInfo.value.transform_.scale_); if (nodeInfo.hasSprite) { StaticSprite2D* staticSprite = node->GetComponent<StaticSprite2D>(); if (staticSprite) { staticSprite->SetOrderInLayer(orderInLayer_ + nodeInfo.value.zIndex_); staticSprite->SetSprite(nodeInfo.value.sprite_); staticSprite->SetUseHotSpot(nodeInfo.value.useHotSpot_); staticSprite->SetHotSpot(nodeInfo.value.hotSpot_); } } } } MarkForUpdate(); }
void AnimatedSprite2D::UpdateAnimation(float timeStep) { if (!animation_) return; currentTime_ += timeStep * speed_; float time; float animtationLength = animation_->GetLength(); if (looped_) { time = fmodf(currentTime_, animtationLength); if (time < 0.0f) time += animation_->GetLength(); } else time = Clamp(currentTime_, 0.0f, animtationLength); // Update timeline's local transform for (unsigned i = 0; i < timelineTransformInfos_.Size(); ++i) { const Timeline2D& timeline = animation_->GetTimeline(i); const Vector<TimelineKey2D>& objectKeys = timeline.timelineKeys_; unsigned index = objectKeys.Size() - 1; for (unsigned j = 0; j < objectKeys.Size() - 1; ++j) { if (time <= objectKeys[j + 1].time_) { index = j; break; } } const TimelineKey2D& currKey = objectKeys[index]; if (index < objectKeys.Size() - 1) { const TimelineKey2D& nextKey = objectKeys[index + 1]; float t = (time - currKey.time_) / (nextKey.time_ - currKey.time_); timelineTransformInfos_[i].worldSpace_ = false; timelineTransformInfos_[i].transform_ = currKey.transform_.Lerp(nextKey.transform_, t, currKey.spin_); // Update sprite's sprite and hot spot and color Node* timelineNode = timelineNodes_[i]; if (timelineNode) { StaticSprite2D* staticSprite = timelineNode->GetComponent<StaticSprite2D>(); if (staticSprite) { staticSprite->SetSprite(currKey.sprite_); staticSprite->SetHotSpot(currKey.hotSpot_.Lerp(nextKey.hotSpot_, t)); float alpha = Lerp(currKey.alpha_, nextKey.alpha_, t); staticSprite->SetColor(Color(color_.r_, color_.g_, color_.b_, color_.a_ * alpha)); } } } else { timelineTransformInfos_[i].worldSpace_ = false; timelineTransformInfos_[i].transform_ = currKey.transform_; // Update sprite's sprite and hot spot and color Node* timelineNode = timelineNodes_[i]; if (timelineNode) { StaticSprite2D* staticSprite = timelineNode->GetComponent<StaticSprite2D>(); if (staticSprite) { staticSprite->SetSprite(currKey.sprite_); staticSprite->SetHotSpot(currKey.hotSpot_); staticSprite->SetColor(Color(color_.r_, color_.g_, color_.b_, color_.a_ * currKey.alpha_)); } } } } // Calculate timeline world transform. for (unsigned i = 0; i < timelineTransformInfos_.Size(); ++i) CalculateTimelineWorldTransform(i); // Get mainline key const Vector<MainlineKey2D>& mainlineKeys = animation_->GetMainlineKeys(); const MainlineKey2D* mainlineKey = 0; for (unsigned i = 1; i < mainlineKeys.Size(); ++i) { if (time < mainlineKeys[i].time_) { mainlineKey = &mainlineKeys[i - 1]; break; } } if (!mainlineKey) mainlineKey = &mainlineKeys.Back(); // Update node's transform and sprite's z order for (unsigned i = 0; i < timelineNodes_.Size(); ++i) { Node* timelineNode = timelineNodes_[i]; if (!timelineNode) continue; const Reference2D* ref = mainlineKey->GetReference(i); if (!ref) { // Disable node if (timelineNode->IsEnabled()) timelineNode->SetEnabled(false); } else { // Enable node if (!timelineNode->IsEnabled()) timelineNode->SetEnabled(true); // Update node's transform const Transform2D& transform = timelineTransformInfos_[i].transform_; Vector2 position = transform.position_ * PIXEL_SIZE; if (flipX_) position.x_ = -position.x_; if (flipY_) position.y_ = -position.y_; timelineNode->SetPosition(position); float angle = transform.angle_; if (flipX_ != flipY_) angle = -angle; timelineNode->SetRotation(angle); timelineNode->SetScale(transform.scale_); // Update sprite's z order StaticSprite2D* staticSprite = timelineNode->GetComponent<StaticSprite2D>(); if (staticSprite) staticSprite->SetOrderInLayer(orderInLayer_ + ref->zIndex_); } } MarkForUpdate(); }
void Urho2DConstraints::CreateScene() { scene_ = new Scene(context_); scene_->CreateComponent<Octree>(); scene_->CreateComponent<DebugRenderer>(); PhysicsWorld2D* physicsWorld = scene_->CreateComponent<PhysicsWorld2D>(); // Create 2D physics world component physicsWorld->SetDrawJoint(true); // Display the joints (Note that DrawDebugGeometry() must be set to true to acually draw the joints) drawDebug_ = true; // Set DrawDebugGeometry() to true // Create camera cameraNode_ = scene_->CreateChild("Camera"); // Set camera's position cameraNode_->SetPosition(Vector3(0.0f, 0.0f, 0.0f)); // Note that Z setting is discarded; use camera.zoom instead (see MoveCamera() below for example) camera_ = cameraNode_->CreateComponent<Camera>(); camera_->SetOrthographic(true); Graphics* graphics = GetSubsystem<Graphics>(); camera_->SetOrthoSize((float)graphics->GetHeight() * PIXEL_SIZE); camera_->SetZoom(1.2f); // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen SharedPtr<Viewport> viewport(new Viewport(context_, scene_, camera_)); Renderer* renderer = GetSubsystem<Renderer>(); renderer->SetViewport(0, viewport); Zone* zone = renderer->GetDefaultZone(); zone->SetFogColor(Color(0.1f, 0.1f, 0.1f)); // Set background color for the scene // Create 4x3 grid for (unsigned i = 0; i<5; ++i) { Node* edgeNode = scene_->CreateChild("VerticalEdge"); RigidBody2D* edgeBody = edgeNode->CreateComponent<RigidBody2D>(); if (!dummyBody) dummyBody = edgeBody; // Mark first edge as dummy body (used by mouse pick) CollisionEdge2D* edgeShape = edgeNode->CreateComponent<CollisionEdge2D>(); edgeShape->SetVertices(Vector2(i*2.5f -5.0f, -3.0f), Vector2(i*2.5f -5.0f, 3.0f)); edgeShape->SetFriction(0.5f); // Set friction } for (unsigned j = 0; j<4; ++j) { Node* edgeNode = scene_->CreateChild("HorizontalEdge"); RigidBody2D* edgeBody = edgeNode->CreateComponent<RigidBody2D>(); CollisionEdge2D* edgeShape = edgeNode->CreateComponent<CollisionEdge2D>(); edgeShape->SetVertices(Vector2(-5.0f, j*2.0f -3.0f), Vector2(5.0f, j*2.0f -3.0f)); edgeShape->SetFriction(0.5f); // Set friction } ResourceCache* cache = GetSubsystem<ResourceCache>(); // Create a box (will be cloned later) Node* box = scene_->CreateChild("Box"); box->SetPosition(Vector3(0.8f, -2.0f, 0.0f)); StaticSprite2D* boxSprite = box->CreateComponent<StaticSprite2D>(); boxSprite->SetSprite(cache->GetResource<Sprite2D>("Urho2D/Box.png")); RigidBody2D* boxBody = box->CreateComponent<RigidBody2D>(); boxBody->SetBodyType(BT_DYNAMIC); boxBody->SetLinearDamping(0.0f); boxBody->SetAngularDamping(0.0f); CollisionBox2D* shape = box->CreateComponent<CollisionBox2D>(); // Create box shape shape->SetSize(Vector2(0.32, 0.32)); // Set size shape->SetDensity(1.0f); // Set shape density (kilograms per meter squared) shape->SetFriction(0.5f); // Set friction shape->SetRestitution(0.1f); // Set restitution (slight bounce) // Create a ball (will be cloned later) Node* ball = scene_->CreateChild("Ball"); ball->SetPosition(Vector3(1.8f, -2.0f, 0.0f)); StaticSprite2D* ballSprite = ball->CreateComponent<StaticSprite2D>(); ballSprite->SetSprite(cache->GetResource<Sprite2D>("Urho2D/Ball.png")); RigidBody2D* ballBody = ball->CreateComponent<RigidBody2D>(); ballBody->SetBodyType(BT_DYNAMIC); ballBody->SetLinearDamping(0.0f); ballBody->SetAngularDamping(0.0f); CollisionCircle2D* ballShape = ball->CreateComponent<CollisionCircle2D>(); // Create circle shape ballShape->SetRadius(0.16f); // Set radius ballShape->SetDensity(1.0f); // Set shape density (kilograms per meter squared) ballShape->SetFriction(0.5f); // Set friction ballShape->SetRestitution(0.6f); // Set restitution: make it bounce // Create a polygon Node* polygon = scene_->CreateChild("Polygon"); polygon->SetPosition(Vector3(1.6f, -2.0f, 0.0f)); polygon->SetScale(0.7f); StaticSprite2D* polygonSprite = polygon->CreateComponent<StaticSprite2D>(); polygonSprite->SetSprite(cache->GetResource<Sprite2D>("Urho2D/Aster.png")); RigidBody2D* polygonBody = polygon->CreateComponent<RigidBody2D>(); polygonBody->SetBodyType(BT_DYNAMIC); CollisionPolygon2D* polygonShape = polygon->CreateComponent<CollisionPolygon2D>(); // TODO: create from PODVector<Vector2> using SetVertices() polygonShape->SetVertexCount(6); // Set number of vertices (mandatory when using SetVertex()) polygonShape->SetVertex(0, Vector2(-0.8f, -0.3f)); polygonShape->SetVertex(1, Vector2(0.5f, -0.8f)); polygonShape->SetVertex(2, Vector2(0.8f, -0.3f)); polygonShape->SetVertex(3, Vector2(0.8f, 0.5f)); polygonShape->SetVertex(4, Vector2(0.5f, 0.9f)); polygonShape->SetVertex(5, Vector2(-0.5f, 0.7f)); polygonShape->SetDensity(1.0f); // Set shape density (kilograms per meter squared) polygonShape->SetFriction(0.3f); // Set friction polygonShape->SetRestitution(0.0f); // Set restitution (no bounce) // Create a ConstraintDistance2D CreateFlag("ConstraintDistance2D", -4.97f, 3.0f); // Display Text3D flag Node* boxDistanceNode = box->Clone(); Node* ballDistanceNode = ball->Clone(); RigidBody2D* ballDistanceBody = ballDistanceNode->GetComponent<RigidBody2D>(); boxDistanceNode->SetPosition(Vector3(-4.5f, 2.0f, 0.0f)); ballDistanceNode->SetPosition(Vector3(-3.0f, 2.0f, 0.0f)); ConstraintDistance2D* constraintDistance = boxDistanceNode->CreateComponent<ConstraintDistance2D>(); // Apply ConstraintDistance2D to box constraintDistance->SetOtherBody(ballDistanceBody); // Constrain ball to box constraintDistance->SetOwnerBodyAnchor(Vector2(boxDistanceNode->GetPosition().x_, boxDistanceNode->GetPosition().y_)); constraintDistance->SetOtherBodyAnchor(Vector2(ballDistanceNode->GetPosition().x_, ballDistanceNode->GetPosition().y_)); // Make the constraint soft (comment to make it rigid, which is its basic behavior) constraintDistance->SetFrequencyHz(4.0f); constraintDistance->SetDampingRatio(0.5f); // Create a ConstraintFriction2D ********** Not functional. From Box2d samples it seems that 2 anchors are required, Urho2D only provides 1, needs investigation *********** CreateFlag("ConstraintFriction2D", 0.03f, 1.0f); // Display Text3D flag Node* boxFrictionNode = box->Clone(); Node* ballFrictionNode = ball->Clone(); boxFrictionNode->SetPosition(Vector3(0.5f, 0.0f, 0.0f)); ballFrictionNode->SetPosition(Vector3(1.5f, 0.0f, 0.0f)); ConstraintFriction2D* constraintFriction = boxFrictionNode->CreateComponent<ConstraintFriction2D>(); // Apply ConstraintDistance2D to box constraintFriction->SetOtherBody(ballFrictionNode->GetComponent<RigidBody2D>()); // Constraint ball to box //constraintFriction->SetOwnerBodyAnchor(Vector2(boxNode->GetPosition().x_, boxNode->GetPosition().y_); //constraintFriction->SetOtherBodyAnchor(Vector2(ballNode->GetPosition().x_, ballNode->GetPosition().y_); //constraintFriction->SetMaxForce(10.0f); // ballBody.mass * gravity //constraintDistance->SetMaxTorque(10.0f); // ballBody.mass * radius * gravity // Create a ConstraintGear2D CreateFlag("ConstraintGear2D", -4.97f, -1.0f); // Display Text3D flag Node* baseNode = box->Clone(); RigidBody2D* tempBody = baseNode->GetComponent<RigidBody2D>(); // Get body to make it static tempBody->SetBodyType(BT_STATIC); baseNode->SetPosition(Vector3(-3.7f, -2.5f, 0.0f)); Node* ball1Node = ball->Clone(); ball1Node->SetPosition(Vector3(-4.5f, -2.0f, 0.0f)); RigidBody2D* ball1Body = ball1Node->GetComponent<RigidBody2D>(); Node* ball2Node = ball->Clone(); ball2Node->SetPosition(Vector3(-3.0f, -2.0f, 0.0f)); RigidBody2D* ball2Body = ball2Node->GetComponent<RigidBody2D>(); ConstraintRevolute2D* gear1 = baseNode->CreateComponent<ConstraintRevolute2D>(); // Apply constraint to baseBox gear1->SetOtherBody(ball1Body); // Constrain ball1 to baseBox gear1->SetAnchor(Vector2(ball1Node->GetPosition().x_, ball1Node->GetPosition().y_)); ConstraintRevolute2D* gear2 = baseNode->CreateComponent<ConstraintRevolute2D>(); // Apply constraint to baseBox gear2->SetOtherBody(ball2Body); // Constrain ball2 to baseBox gear2->SetAnchor(Vector2(ball2Node->GetPosition().x_, ball2Node->GetPosition().y_)); ConstraintGear2D* constraintGear = ball1Node->CreateComponent<ConstraintGear2D>(); // Apply constraint to ball1 constraintGear->SetOtherBody(ball2Body); // Constrain ball2 to ball1 constraintGear->SetOwnerConstraint(gear1); constraintGear->SetOtherConstraint(gear2); constraintGear->SetRatio(1.0f); ball1Body->ApplyAngularImpulse(0.015f, true); // Animate // Create a vehicle from a compound of 2 ConstraintWheel2Ds CreateFlag("ConstraintWheel2Ds compound", -2.45f, -1.0f); // Display Text3D flag Node* car = box->Clone(); car->SetScale(Vector3(4.0f, 1.0f, 0.0f)); car->SetPosition(Vector3(-1.2f, -2.3f, 0.0f)); StaticSprite2D* tempSprite = car->GetComponent<StaticSprite2D>(); // Get car Sprite in order to draw it on top tempSprite->SetOrderInLayer(0); // Draw car on top of the wheels (set to -1 to draw below) Node* ball1WheelNode = ball->Clone(); ball1WheelNode->SetPosition(Vector3(-1.6f, -2.5f, 0.0f)); Node* ball2WheelNode = ball->Clone(); ball2WheelNode->SetPosition(Vector3(-0.8f, -2.5f, 0.0f)); ConstraintWheel2D* wheel1 = car->CreateComponent<ConstraintWheel2D>(); wheel1->SetOtherBody(ball1WheelNode->GetComponent<RigidBody2D>()); wheel1->SetAnchor(Vector2(ball1WheelNode->GetPosition().x_, ball1WheelNode->GetPosition().y_)); wheel1->SetAxis(Vector2(0.0f, 1.0f)); wheel1->SetMaxMotorTorque(20.0f); wheel1->SetFrequencyHz(4.0f); wheel1->SetDampingRatio(0.4f); ConstraintWheel2D* wheel2 = car->CreateComponent<ConstraintWheel2D>(); wheel2->SetOtherBody(ball2WheelNode->GetComponent<RigidBody2D>()); wheel2->SetAnchor(Vector2(ball2WheelNode->GetPosition().x_, ball2WheelNode->GetPosition().y_)); wheel2->SetAxis(Vector2(0.0f, 1.0f)); wheel2->SetMaxMotorTorque(10.0f); wheel2->SetFrequencyHz(4.0f); wheel2->SetDampingRatio(0.4f); // ConstraintMotor2D CreateFlag("ConstraintMotor2D", 2.53f, -1.0f); // Display Text3D flag Node* boxMotorNode = box->Clone(); tempBody = boxMotorNode->GetComponent<RigidBody2D>(); // Get body to make it static tempBody->SetBodyType(BT_STATIC); Node* ballMotorNode = ball->Clone(); boxMotorNode->SetPosition(Vector3(3.8f, -2.1f, 0.0f)); ballMotorNode->SetPosition(Vector3(3.8f, -1.5f, 0.0f)); ConstraintMotor2D* constraintMotor = boxMotorNode->CreateComponent<ConstraintMotor2D>(); constraintMotor->SetOtherBody(ballMotorNode->GetComponent<RigidBody2D>()); // Constrain ball to box constraintMotor->SetLinearOffset(Vector2(0.0f, 0.8f)); // Set ballNode position relative to boxNode position = (0,0) constraintMotor->SetAngularOffset(0.1f); constraintMotor->SetMaxForce(5.0f); constraintMotor->SetMaxTorque(10.0f); constraintMotor->SetCorrectionFactor(1.0f); constraintMotor->SetCollideConnected(true); // doesn't work // ConstraintMouse2D is demonstrated in HandleMouseButtonDown() function. It is used to "grasp" the sprites with the mouse. CreateFlag("ConstraintMouse2D", 0.03f, -1.0f); // Display Text3D flag // Create a ConstraintPrismatic2D CreateFlag("ConstraintPrismatic2D", 2.53f, 3.0f); // Display Text3D flag Node* boxPrismaticNode = box->Clone(); tempBody = boxPrismaticNode->GetComponent<RigidBody2D>(); // Get body to make it static tempBody->SetBodyType(BT_STATIC); Node* ballPrismaticNode = ball->Clone(); boxPrismaticNode->SetPosition(Vector3(3.3f, 2.5f, 0.0f)); ballPrismaticNode->SetPosition(Vector3(4.3f, 2.0f, 0.0f)); ConstraintPrismatic2D* constraintPrismatic = boxPrismaticNode->CreateComponent<ConstraintPrismatic2D>(); constraintPrismatic->SetOtherBody(ballPrismaticNode->GetComponent<RigidBody2D>()); // Constrain ball to box constraintPrismatic->SetAxis(Vector2(1.0f, 1.0f)); // Slide from [0,0] to [1,1] constraintPrismatic->SetAnchor(Vector2(4.0f, 2.0f)); constraintPrismatic->SetLowerTranslation(-1.0f); constraintPrismatic->SetUpperTranslation(0.5f); constraintPrismatic->SetEnableLimit(true); constraintPrismatic->SetMaxMotorForce(1.0f); constraintPrismatic->SetMotorSpeed(0.0f); // ConstraintPulley2D CreateFlag("ConstraintPulley2D", 0.03f, 3.0f); // Display Text3D flag Node* boxPulleyNode = box->Clone(); Node* ballPulleyNode = ball->Clone(); boxPulleyNode->SetPosition(Vector3(0.5f, 2.0f, 0.0f)); ballPulleyNode->SetPosition(Vector3(2.0f, 2.0f, 0.0f)); ConstraintPulley2D* constraintPulley = boxPulleyNode->CreateComponent<ConstraintPulley2D>(); // Apply constraint to box constraintPulley->SetOtherBody(ballPulleyNode->GetComponent<RigidBody2D>()); // Constrain ball to box constraintPulley->SetOwnerBodyAnchor(Vector2(boxPulleyNode->GetPosition().x_, boxPulleyNode->GetPosition().y_)); constraintPulley->SetOtherBodyAnchor(Vector2(ballPulleyNode->GetPosition().x_, ballPulleyNode->GetPosition().y_)); constraintPulley->SetOwnerBodyGroundAnchor(Vector2(boxPulleyNode->GetPosition().x_, boxPulleyNode->GetPosition().y_ + 1)); constraintPulley->SetOtherBodyGroundAnchor(Vector2(ballPulleyNode->GetPosition().x_, ballPulleyNode->GetPosition().y_ + 1)); constraintPulley->SetRatio(1.0); // Weight ratio between ownerBody and otherBody // Create a ConstraintRevolute2D CreateFlag("ConstraintRevolute2D", -2.45f, 3.0f); // Display Text3D flag Node* boxRevoluteNode = box->Clone(); tempBody = boxRevoluteNode->GetComponent<RigidBody2D>(); // Get body to make it static tempBody->SetBodyType(BT_STATIC); Node* ballRevoluteNode = ball->Clone(); boxRevoluteNode->SetPosition(Vector3(-2.0f, 1.5f, 0.0f)); ballRevoluteNode->SetPosition(Vector3(-1.0f, 2.0f, 0.0f)); ConstraintRevolute2D* constraintRevolute = boxRevoluteNode->CreateComponent<ConstraintRevolute2D>(); // Apply constraint to box constraintRevolute->SetOtherBody(ballRevoluteNode->GetComponent<RigidBody2D>()); // Constrain ball to box constraintRevolute->SetAnchor(Vector2(-1.0f, 1.5f)); constraintRevolute->SetLowerAngle(-1.0f); // In radians constraintRevolute->SetUpperAngle(0.5f); // In radians constraintRevolute->SetEnableLimit(true); constraintRevolute->SetMaxMotorTorque(10.0f); constraintRevolute->SetMotorSpeed(0.0f); constraintRevolute->SetEnableMotor(true); // Create a ConstraintRope2D CreateFlag("ConstraintRope2D", -4.97f, 1.0f); // Display Text3D flag Node* boxRopeNode = box->Clone(); tempBody = boxRopeNode->GetComponent<RigidBody2D>(); tempBody->SetBodyType(BT_STATIC); Node* ballRopeNode = ball->Clone(); boxRopeNode->SetPosition(Vector3(-3.7f, 0.7f, 0.0f)); ballRopeNode->SetPosition(Vector3(-4.5f, 0.0f, 0.0f)); ConstraintRope2D* constraintRope = boxRopeNode->CreateComponent<ConstraintRope2D>(); constraintRope->SetOtherBody(ballRopeNode->GetComponent<RigidBody2D>()); // Constrain ball to box constraintRope->SetOwnerBodyAnchor(Vector2(0.0f, -0.5f)); // Offset from box (OwnerBody) : the rope is rigid from OwnerBody center to this ownerBodyAnchor constraintRope->SetMaxLength(0.9f); // Rope length constraintRope->SetCollideConnected(true); // Create a ConstraintWeld2D CreateFlag("ConstraintWeld2D", -2.45f, 1.0f); // Display Text3D flag Node* boxWeldNode = box->Clone(); Node* ballWeldNode = ball->Clone(); boxWeldNode->SetPosition(Vector3(-0.5f, 0.0f, 0.0f)); ballWeldNode->SetPosition(Vector3(-2.0f, 0.0f, 0.0f)); ConstraintWeld2D* constraintWeld = boxWeldNode->CreateComponent<ConstraintWeld2D>(); constraintWeld->SetOtherBody(ballWeldNode->GetComponent<RigidBody2D>()); // Constrain ball to box constraintWeld->SetAnchor(Vector2(boxWeldNode->GetPosition().x_, boxWeldNode->GetPosition().y_)); constraintWeld->SetFrequencyHz(4.0f); constraintWeld->SetDampingRatio(0.5f); // Create a ConstraintWheel2D CreateFlag("ConstraintWheel2D", 2.53f, 1.0f); // Display Text3D flag Node* boxWheelNode = box->Clone(); Node* ballWheelNode = ball->Clone(); boxWheelNode->SetPosition(Vector3(3.8f, 0.0f, 0.0f)); ballWheelNode->SetPosition(Vector3(3.8f, 0.9f, 0.0f)); ConstraintWheel2D* constraintWheel = boxWheelNode->CreateComponent<ConstraintWheel2D>(); constraintWheel->SetOtherBody(ballWheelNode->GetComponent<RigidBody2D>()); // Constrain ball to box constraintWheel->SetAnchor(Vector2(ballWheelNode->GetPosition().x_, ballWheelNode->GetPosition().y_)); constraintWheel->SetAxis(Vector2(0.0f, 1.0f)); constraintWheel->SetEnableMotor(true); constraintWheel->SetMaxMotorTorque(1.0f); constraintWheel->SetMotorSpeed(0.0f); constraintWheel->SetFrequencyHz(4.0f); constraintWheel->SetDampingRatio(0.5f); constraintWheel->SetCollideConnected(true); // doesn't work }