Esempio n. 1
0
RID DampedSpringJoint2D::_configure_joint() {

	Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
	Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;

	if (!node_a || !node_b)
		return RID();

	PhysicsBody2D *body_a = node_a->cast_to<PhysicsBody2D>();
	PhysicsBody2D *body_b = node_b->cast_to<PhysicsBody2D>();

	if (!body_a || !body_b)
		return RID();

	if (get_exclude_nodes_from_collision())
		Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
	else
		Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());

	Transform2D gt = get_global_transform();
	Vector2 anchor_A = gt.get_origin();
	Vector2 anchor_B = gt.xform(Vector2(0, length));

	RID dsj = Physics2DServer::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid());
	if (rest_length)
		Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_REST_LENGTH, rest_length);
	Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_STIFFNESS, stiffness);
	Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_DAMPING, damping);

	return dsj;
}
Esempio n. 2
0
	void Transform2D::UpdateHierarchy()
	{
		m_bDirty = false;
		Matrix localMatrix;
		// Rebuild your local Matrix
		RebuildTransform(localMatrix);
		
		// Factor in the parent transform
		Transform2D* parent = m_node.GetParent();
		if (parent)
		{
			m_worldMatrix = parent->GetWorldTransform();
			m_worldMatrix.SelfMultiply(localMatrix);
		}
		else
		{
			m_worldMatrix = localMatrix;
		}
		
		// Rebuild the bounds
		RebuildBounds(m_worldBounds, m_dimensions);
		
		// Rebuild the preserved bounds, if there are any
		if (HasPreservedAspect())
			RebuildBounds(m_worldBoundsPreserved, m_dimensionsPreserved);
		
		// Inform your children of these updates
		Transform2D* childTransform = m_node.GetChild();
		while (childTransform)
		{
			childTransform->UpdateHierarchy();
			childTransform = childTransform->m_node.GetSibling();
		}
	}
Esempio n. 3
0
        Transform2D Transform3D::projectTo2D(const arma::vec3& yawAxis, const arma::vec3& forwardAxis) const {
            Transform2D result;

            // Translation
            arma::vec3 orthoForwardAxis = arma::normalise(arma::cross(yawAxis, arma::cross(forwardAxis, yawAxis)));
            arma::vec3 r                = translation();
            Rotation3D newSpaceToWorld;
            newSpaceToWorld.x()        = orthoForwardAxis;
            newSpaceToWorld.y()        = arma::cross(yawAxis, orthoForwardAxis);
            newSpaceToWorld.z()        = yawAxis;
            Rotation3D worldToNewSpace = newSpaceToWorld.i();
            arma::vec3 rNewSpace       = worldToNewSpace * r;
            result.xy()                = rNewSpace.rows(0, 1);

            // Rotation
            Rotation3D rot       = rotation();
            arma::vec3 x         = rot.x();
            arma::vec3 xNew      = worldToNewSpace * x;
            float theta_x_from_f = std::atan2(xNew[1], xNew[0]);  // sin/cos
            result.angle()       = theta_x_from_f;

            // std::cerr << "in = \n" << *this << std::endl;
            // std::cerr << "out = \n" << result << std::endl;
            return result;
        }
Esempio n. 4
0
void RayCast2D::_update_raycast_state() {
	Ref<World2D> w2d = get_world_2d();
	ERR_FAIL_COND(w2d.is_null());

	Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(w2d->get_space());
	ERR_FAIL_COND(!dss);

	Transform2D gt = get_global_transform();

	Vector2 to = cast_to;
	if (to == Vector2())
		to = Vector2(0, 0.01);

	Physics2DDirectSpaceState::RayResult rr;

	if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_layer, type_mask)) {

		collided = true;
		against = rr.collider_id;
		collision_point = rr.position;
		collision_normal = rr.normal;
		against_shape = rr.shape;
	} else {
		collided = false;
	}
}
Esempio n. 5
0
	const vec2 Transform2D::ParentSpaceToChildSpace(const vec2& parentSpacePosition) const
	{
		vec2 childSpacePosition = parentSpacePosition;

		__todo() //does this work without rotation?
			vec2 unscale = vec2(1.0f, 1.0f);
		vec2 untranslate = vec2(0.0f, 0.0f);
		Transform2D* parent = m_node.GetParent();
		while (parent)
		{
			const vec2& parentScale = parent->GetScale();
			unscale.x *= parentScale.x;
			unscale.y *= parentScale.y;

			const vec2& parentPos = parent->GetPosition();
			untranslate.x += parentPos.x;
			untranslate.y += parentPos.y;

			parent = parent->m_node.GetParent();
		}

		// 'un-apply' the translation
		childSpacePosition -= untranslate;

		// 'un-apply' the scale
		childSpacePosition.x /= unscale.x;
		childSpacePosition.y /= unscale.y;

		return childSpacePosition;
	}
Esempio n. 6
0
void ProcAbsPos::addTestPointsAtTo(Mat& im, ProjAcq& pAcq, const Transform2D<float>& tr_rob2pg) const {
    Transform2D<float> tr_pg2rob = tr_rob2pg.getReverse();
    Cam const* cam = pAcq.getAcq()->getCam();

    // get corners and edges of cam fov projected on playground
    Mat camCorners[4];
    camCorners[0] = tr_rob2pg.transformLinPos(pAcq.cam2plane(cam->getTopLeft()));
    camCorners[1] = tr_rob2pg.transformLinPos(pAcq.cam2plane(cam->getTopRight()));
    camCorners[2] = tr_rob2pg.transformLinPos(pAcq.cam2plane(cam->getBottomRight()));
    camCorners[3] = tr_rob2pg.transformLinPos(pAcq.cam2plane(cam->getBottomLeft()));

    float xMin = MIN(MIN(camCorners[0].at<float>(0), camCorners[1].at<float>(0)), MIN(camCorners[2].at<float>(0), camCorners[3].at<float>(0)));
    float yMin = MIN(MIN(camCorners[0].at<float>(1), camCorners[1].at<float>(1)), MIN(camCorners[2].at<float>(1), camCorners[3].at<float>(1)));
    float xMax = MAX(MAX(camCorners[0].at<float>(0), camCorners[1].at<float>(0)), MAX(camCorners[2].at<float>(0), camCorners[3].at<float>(0)));
    float yMax = MAX(MAX(camCorners[0].at<float>(1), camCorners[1].at<float>(1)), MAX(camCorners[2].at<float>(1), camCorners[3].at<float>(1)));

    Mat camEdges[4];
    for (int i = 0; i < 4; i++) {
        camEdges[i] = camCorners[(i + 1) % 4] - camCorners[i];
    }

    for (TestPoint const& tp : staticTP) {
        cv::Mat tp_pos = tp.getPos();

        float tp_x = tp_pos.at<float>(0);
        float tp_y = tp_pos.at<float>(1);

        if (tp_x > xMax || tp_x < xMin || tp_y > yMax || tp_y < yMin) {
            continue;
        }

        // check if testpoint seen by camera
        int i;
        for (i = 0; i < 4; i++) {
            Mat vi = tp_pos - camCorners[i];

            double cross = vi.at<float>(0) * camEdges[i].at<float>(1) -
                    vi.at<float>(1) * camEdges[i].at<float>(0);
            if (cross < 0) {
                break;
            }
        }
        if (i < 4) {
            continue;
        }

        // get position of testpoint in original camera image
        cv::Mat tp_cmRob = tr_pg2rob.transformLinPos(tp_pos);
        cv::Mat tp_pxCam = pAcq.plane2cam(tp_cmRob);

        int x = int(round(tp_pxCam.at<float>(0)));
        int y = int(round(tp_pxCam.at<float>(1)));

        assert(x >= 0 && x < cam->getSize().width);
        assert(y >= 0 && y < cam->getSize().height);

        // draw testpoint position in camera frame
        im.at<Vec3b>(y, x) = Vec3b(255, 255, 255);
    }
}
Esempio n. 7
0
void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) {
	ERR_FAIL_COND(!_edit_use_rect());

	Rect2 r = _edit_get_rect();

	Vector2 zero_offset;
	if (r.size.x != 0)
		zero_offset.x = -r.position.x / r.size.x;
	if (r.size.y != 0)
		zero_offset.y = -r.position.y / r.size.y;

	Size2 new_scale(1, 1);

	if (r.size.x != 0)
		new_scale.x = p_edit_rect.size.x / r.size.x;
	if (r.size.y != 0)
		new_scale.y = p_edit_rect.size.y / r.size.y;

	Point2 new_pos = p_edit_rect.position + p_edit_rect.size * zero_offset;

	Transform2D postxf;
	postxf.set_rotation_and_scale(angle, _scale);
	new_pos = postxf.xform(new_pos);

	pos += new_pos;
	_scale *= new_scale;

	_update_transform();
	_change_notify("scale");
	_change_notify("position");
}
Esempio n. 8
0
RID GrooveJoint2D::_configure_joint() {

	Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
	Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;

	if (!node_a || !node_b)
		return RID();

	PhysicsBody2D *body_a = node_a->cast_to<PhysicsBody2D>();
	PhysicsBody2D *body_b = node_b->cast_to<PhysicsBody2D>();

	if (!body_a || !body_b)
		return RID();

	if (get_exclude_nodes_from_collision())
		Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
	else
		Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());

	Transform2D gt = get_global_transform();
	Vector2 groove_A1 = gt.get_origin();
	Vector2 groove_A2 = gt.xform(Vector2(0, length));
	Vector2 anchor_B = gt.xform(Vector2(0, initial_offset));

	return Physics2DServer::get_singleton()->groove_joint_create(groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid());
}
void CollisionPolygon2DEditor::_canvas_draw() {

	if (!node)
		return;

	Control *vpc = canvas_item_editor->get_viewport_control();

	Vector<Vector2> poly;

	if (wip_active)
		poly = wip;
	else
		poly = node->get_polygon();

	Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
	Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");

	for (int i = 0; i < poly.size(); i++) {

		Vector2 p, p2;
		p = i == edited_point ? edited_point_pos : poly[i];
		if ((wip_active && i == poly.size() - 1) || (((i + 1) % poly.size()) == edited_point))
			p2 = edited_point_pos;
		else
			p2 = poly[(i + 1) % poly.size()];

		Vector2 point = xform.xform(p);
		Vector2 next_point = xform.xform(p2);

		Color col = Color(1, 0.3, 0.1, 0.8);
		vpc->draw_line(point, next_point, col, 2);
		vpc->draw_texture(handle, point - handle->get_size() * 0.5);
	}
}
Esempio n. 10
0
RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {

	Transform2D gt = get_global_transform();
	Vector2 groove_A1 = gt.get_origin();
	Vector2 groove_A2 = gt.xform(Vector2(0, length));
	Vector2 anchor_B = gt.xform(Vector2(0, initial_offset));

	return Physics2DServer::get_singleton()->groove_joint_create(groove_A1, groove_A2, anchor_B, body_a->get_rid(), body_b->get_rid());
}
Esempio n. 11
0
void Node2D::set_global_position(const Point2 &p_pos) {

	Transform2D inv;
	CanvasItem *pi = get_parent_item();
	if (pi) {
		inv = pi->get_global_transform().affine_inverse();
		set_position(inv.xform(p_pos));
	} else {
		set_position(p_pos);
	}
}
Esempio n. 12
0
bool TileSet::_set(const StringName &p_name, const Variant &p_value) {

	String n = p_name;
	int slash = n.find("/");
	if (slash == -1)
		return false;
	int id = String::to_int(n.c_str(), slash);

	if (!tile_map.has(id))
		create_tile(id);
	String what = n.substr(slash + 1, n.length());

	if (what == "name")
		tile_set_name(id, p_value);
	else if (what == "texture")
		tile_set_texture(id, p_value);
	else if (what == "normal_map")
		tile_set_normal_map(id, p_value);
	else if (what == "tex_offset")
		tile_set_texture_offset(id, p_value);
	else if (what == "material")
		tile_set_material(id, p_value);
	else if (what == "modulate")
		tile_set_modulate(id, p_value);
	else if (what == "region")
		tile_set_region(id, p_value);
	else if (what == "shape")
		tile_set_shape(id, 0, p_value);
	else if (what == "shape_offset") {
		Transform2D xform = tile_get_shape_transform(id, 0);
		xform.set_origin(p_value);
		tile_set_shape_transform(id, 0, xform);
	} else if (what == "shape_transform")
		tile_set_shape_transform(id, 0, p_value);
	else if (what == "shape_one_way")
		tile_set_shape_one_way(id, 0, p_value);
	else if (what == "shapes")
		_tile_set_shapes(id, p_value);
	else if (what == "occluder")
		tile_set_light_occluder(id, p_value);
	else if (what == "occluder_offset")
		tile_set_occluder_offset(id, p_value);
	else if (what == "navigation")
		tile_set_navigation_polygon(id, p_value);
	else if (what == "navigation_offset")
		tile_set_navigation_polygon_offset(id, p_value);
	else
		return false;

	return true;
}
Esempio n. 13
0
bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const Transform2D &p_xform_A, Body2DSW *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result) {

	Vector2 motion = p_A->get_linear_velocity() * p_step;
	real_t mlen = motion.length();
	if (mlen < CMP_EPSILON)
		return false;

	Vector2 mnormal = motion / mlen;

	real_t min, max;
	p_A->get_shape(p_shape_A)->project_rangev(mnormal, p_xform_A, min, max);
	bool fast_object = mlen > (max - min) * 0.3; //going too fast in that direction

	if (!fast_object) { //did it move enough in this direction to even attempt raycast? let's say it should move more than 1/3 the size of the object in that axis
		return false;
	}

	//cast a segment from support in motion normal, in the same direction of motion by motion length
	//support is the worst case collision point, so real collision happened before
	int a;
	Vector2 s[2];
	p_A->get_shape(p_shape_A)->get_supports(p_xform_A.basis_xform(mnormal).normalized(), s, a);
	Vector2 from = p_xform_A.xform(s[0]);
	Vector2 to = from + motion;

	Transform2D from_inv = p_xform_B.affine_inverse();

	Vector2 local_from = from_inv.xform(from - mnormal * mlen * 0.1); //start from a little inside the bounding box
	Vector2 local_to = from_inv.xform(to);

	Vector2 rpos, rnorm;
	if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm))
		return false;

	//ray hit something

	Vector2 hitpos = p_xform_B.xform(rpos);

	Vector2 contact_A = to;
	Vector2 contact_B = hitpos;

	//create a contact

	if (p_swap_result)
		_contact_added_callback(contact_B, contact_A);
	else
		_contact_added_callback(contact_A, contact_B);

	return true;
}
Esempio n. 14
0
RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {

	Transform2D gt = get_global_transform();
	Vector2 anchor_A = gt.get_origin();
	Vector2 anchor_B = gt.xform(Vector2(0, length));

	RID dsj = Physics2DServer::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid());
	if (rest_length)
		Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_REST_LENGTH, rest_length);
	Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_STIFFNESS, stiffness);
	Physics2DServer::get_singleton()->damped_string_joint_set_param(dsj, Physics2DServer::DAMPED_STRING_DAMPING, damping);

	return dsj;
}
bool test(const Circle& circle, const RotatedRectangle& rect) {
	/*
		Let E be the centre of the rectangle (i.e. the origin of its local coordinate frame).
		Define the regions A-I as below, where the central region E has the dimensions of the rectangle.
		
		A │ B │ C
		──┼───┼──
		D │ E │ F
		──┼───┼──
		G │ H │ I

		Check distance to side in regions: B, D, F, and H.
		Check distance to corner in regions: A, C, G, and I.
		Region E is always an intersection.
		Note: This diagram and the circle are symmetric, so we can use absolute values to simplify the comparisons.
		i.e.
          hw
		B │ C
		──┼── hh
		E │ F
	*/

	Transform2D trans = rect.getTransform();
	Transform2D pos = trans.worldToLocal({circle.centre(0), circle.centre(1), 0});

	double hw = 0.5 * rect.getSize()(0);
	double hh = 0.5 * rect.getSize()(1);
	double r = circle.radius;

	double x = std::abs(pos(0));
	double y = std::abs(pos(1));

	if (x < hw && y < hh) { // E
		return true;
	}

	if (x < hw && y > hh) { // B
		return y < hh + r;
	}

	if (x > hw && y < hh) { // F
		return x < hw + r;
	}

	// if (x > hw && y > hh) { // C
		arma::vec2 cornerDiff = { hw - x, hh - y };
		return arma::norm(cornerDiff) < r;
	// }
}
Esempio n. 16
0
Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {

	Ref<InputEventScreenDrag> sd;

	sd.instance();

	sd->set_device(get_device());

	sd->set_index(index);
	sd->set_position(p_xform.xform(pos + p_local_ofs));
	sd->set_relative(p_xform.basis_xform(relative));
	sd->set_speed(p_xform.basis_xform(speed));

	return sd;
}
Esempio n. 17
0
	void Transform2D::ValidateCleanliness()
	{
		Transform2D* lastDirty = nullptr;
		Transform2D* curNode = this;
		while (curNode)
		{
			if (curNode->GetIsDirty())
				lastDirty = curNode;
			curNode = curNode->m_node.GetParent();
		}
		if (lastDirty)
		{
			ValidateTransforms(lastDirty);
		}
	}
Esempio n. 18
0
	void Transform2D::UpdateAnchors()
	{
		Box oldBound(m_worldBounds);
		RebuildBounds(m_worldBounds, m_dimensions);

		// Update the preserved data
		UpdatePreservedAspectSizes();

		Transform2D* childTransform = m_node.GetChild();
		while (childTransform)
		{
			childTransform->ApplyAnchors(oldBound);
			childTransform->UpdateAnchors();
			childTransform = childTransform->m_node.GetSibling();
		}
	}
Esempio n. 19
0
/**
    Subtracts the specified transform to this vector. This
    vector translated, then rotated.
*/
void Vect2D::subtract(Transform2D& xform) {

    // translate
    *this -= xform.getLocation();

    // rotate
    subtractRotation(xform);
}
Esempio n. 20
0
/**
    Adds the specified transform to this vector. This vector
    is first rotated, then translated.
*/
void Vect2D::add(Transform2D& xform) {

    // rotate
    addRotation(xform);

    // translate
    *this += xform.getLocation();
}
Esempio n. 21
0
void Area2DSW::set_transform(const Transform2D &p_transform) {

	if (!moved_list.in_list() && get_space())
		get_space()->area_add_to_moved_list(&moved_list);

	_set_transform(p_transform);
	_set_inv_transform(p_transform.affine_inverse());
}
Esempio n. 22
0
void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_transform) {

	ERR_FAIL_INDEX(p_index, shapes.size());

	shapes[p_index].xform = p_transform;
	shapes[p_index].xform_inv = p_transform.affine_inverse();
	_update_shapes();
	_shapes_changed();
}
Esempio n. 23
0
bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {

	Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
	ERR_FAIL_COND_V(!shape, 0);

	Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
	aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
	aabb = aabb.grow(p_margin);

	int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);

	_RestCallbackData2D rcd;
	rcd.best_len = 0;
	rcd.best_object = NULL;
	rcd.best_shape = 0;

	for (int i = 0; i < amount; i++) {

		if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
			continue;

		const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
		int shape_idx = space->intersection_query_subindex_results[i];

		if (p_exclude.has(col_obj->get_self()))
			continue;

		rcd.valid_dir = Vector2();
		rcd.valid_depth = 0;
		rcd.object = col_obj;
		rcd.shape = shape_idx;
		bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
		if (!sc)
			continue;
	}

	if (rcd.best_len == 0)
		return false;

	r_info->collider_id = rcd.best_object->get_instance_id();
	r_info->shape = rcd.best_shape;
	r_info->normal = rcd.best_normal;
	r_info->point = rcd.best_contact;
	r_info->rid = rcd.best_object->get_self();
	r_info->metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
	if (rcd.best_object->get_type() == CollisionObject2DSW::TYPE_BODY) {

		const Body2DSW *body = static_cast<const Body2DSW *>(rcd.best_object);
		Vector2 rel_vec = r_info->point - body->get_transform().get_origin();
		r_info->linear_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();

	} else {
		r_info->linear_velocity = Vector2();
	}

	return true;
}
Esempio n. 24
0
/** Write quadratic edge shape in PostScript format.
 *
 * Given the three points composing a quadratic mesh edge,
 * write the cubic Bezier curve of the same shape in 
 * PostScript format.  The formulas for P1 and P2 
 * at the start of this function will result in the cubic
 * terms of the Bezier curve dropping out, leaving the
 * quadratic curve matching the edge shape function as 
 * described in Section 3.6 of Hughes.  (If you're attempting
 * to verify this, don't forget to adjust for the different
 * parameter ranges: \f$ \xi = 2 t - 1 \f$).
 */
static void write_eps_quadratic_edge( ostream &s,
                                      Transform2D& xform,
                                      Vector3D start,
                                      Vector3D mid, 
                                      Vector3D end )
{
  Vector3D P1 = 1./3 * (4 * mid - end);
  Vector3D P2 = 1./3 * (4 * mid - start);

  int x, y;
  xform.transform( start, x, y );
  s << x << ' ' << y << " moveto" << endl;
  xform.transform( P1, x, y );
  s << x << ' ' << y << ' ';
  xform.transform( P2, x, y );
  s << x << ' ' << y << ' ';
  xform.transform( end, x, y );
  s << x << ' ' << y << " curveto" << endl;
}
Esempio n. 25
0
Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {

	Ref<InputEventScreenTouch> st;
	st.instance();
	st->set_device(get_device());
	st->set_index(index);
	st->set_position(p_xform.xform(pos + p_local_ofs));
	st->set_pressed(pressed);

	return st;
}
Esempio n. 26
0
	STATIC void Transform2D::ValidateTransforms(Transform2D* root)
	{
		Transform2D* curTransform = root;
		while (curTransform != NULL)
		{
			Hierarchy<Transform2D>& curNode = curTransform->m_node;

			// If this transform is dirty, then update the rest of it's hierarchy
			if (curTransform->GetIsDirty())
			{
				// We've got dirt on this transform; we know it's number... Update the transforms on downwards
				curTransform->UpdateHierarchy();
				// Traverse upward to continue our traversal
				while (nullptr != curTransform)
				{
					Hierarchy<Transform2D>& upwardNode = curTransform->m_node;

					// Check if there's a sibling of this node
					if (nullptr != upwardNode.GetSibling())
					{
						curTransform = upwardNode.GetSibling();
						break;
					}
					else
					{
						// If this is the root node, then it's time to leave
						if (root == curTransform)
						{
							curTransform = nullptr;
							break;
						}
						curTransform = upwardNode.GetParent();
					}
				}
			}
			else
			{
				curTransform = curNode.Next();
			}
		}
	}
void NavigationPolygonEditor::_canvas_draw() {

	if (!node)
		return;

	Control *vpc = canvas_item_editor->get_viewport_control();
	if (node->get_navigation_polygon().is_null())
		return;

	Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
	Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");

	for (int j = -1; j < node->get_navigation_polygon()->get_outline_count(); j++) {
		Vector<Vector2> poly;

		if (wip_active && j == edited_outline) {
			poly = wip;
		} else {
			if (j == -1)
				continue;
			poly = Variant(node->get_navigation_polygon()->get_outline(j));
		}

		for (int i = 0; i < poly.size(); i++) {

			Vector2 p, p2;
			p = (j == edited_outline && i == edited_point) ? edited_point_pos : poly[i];
			if (j == edited_outline && ((wip_active && i == poly.size() - 1) || (((i + 1) % poly.size()) == edited_point)))
				p2 = edited_point_pos;
			else
				p2 = poly[(i + 1) % poly.size()];

			Vector2 point = xform.xform(p);
			Vector2 next_point = xform.xform(p2);

			Color col = Color(1, 0.3, 0.1, 0.8);
			vpc->draw_line(point, next_point, col, 2);
			vpc->draw_texture(handle, point - handle->get_size() * 0.5);
		}
	}
}
Esempio n. 28
0
bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis) {

	const RayShape2DSW *ray = static_cast<const RayShape2DSW *>(p_shape_A);
	if (p_shape_B->get_type() == Physics2DServer::SHAPE_RAY)
		return false;

	Vector2 from = p_transform_A.get_origin();
	Vector2 to = from + p_transform_A[1] * ray->get_length();
	Vector2 support_A = to;

	Transform2D invb = p_transform_B.affine_inverse();
	from = invb.xform(from);
	to = invb.xform(to);

	Vector2 p, n;
	if (!p_shape_B->intersect_segment(from, to, p, n)) {

		if (sep_axis)
			*sep_axis = p_transform_A[1].normalized();
		return false;
	}

	Vector2 support_B = p_transform_B.xform(p);

	if (p_result_callback) {
		if (p_swap_result)
			p_result_callback(support_B, support_A, p_userdata);
		else
			p_result_callback(support_A, support_B, p_userdata);
	}
	return true;
}
Esempio n. 29
0
bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {

	if (p_result_max <= 0)
		return 0;

	Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
	ERR_FAIL_COND_V(!shape, 0);

	Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
	aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
	aabb = aabb.grow(p_margin);

	int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);

	bool collided = false;
	r_result_count = 0;

	Physics2DServerSW::CollCbkData cbk;
	cbk.max = p_result_max;
	cbk.amount = 0;
	cbk.ptr = r_results;
	CollisionSolver2DSW::CallbackResult cbkres = NULL;

	Physics2DServerSW::CollCbkData *cbkptr = NULL;
	if (p_result_max > 0) {
		cbkptr = &cbk;
		cbkres = Physics2DServerSW::_shape_col_cbk;
	}

	for (int i = 0; i < amount; i++) {

		if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
			continue;

		const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
		int shape_idx = space->intersection_query_subindex_results[i];

		if (p_exclude.has(col_obj->get_self()))
			continue;

		cbk.valid_dir = Vector2();
		cbk.valid_depth = 0;

		if (CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
			collided = p_result_max == 0 || cbk.amount > 0;
		}
	}

	r_result_count = cbk.amount;

	return collided;
}
Esempio n. 30
0
void RayCast2D::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_ENTER_TREE: {

			if (enabled && !get_tree()->is_editor_hint())
				set_fixed_process(true);
			else
				set_fixed_process(false);

			if (get_parent()->cast_to<PhysicsBody2D>()) {
				if (exclude_parent_body)
					exclude.insert(get_parent()->cast_to<PhysicsBody2D>()->get_rid());
				else
					exclude.erase(get_parent()->cast_to<PhysicsBody2D>()->get_rid());
			}
		} break;
		case NOTIFICATION_EXIT_TREE: {

			if (enabled)
				set_fixed_process(false);

		} break;

		case NOTIFICATION_DRAW: {

			if (!get_tree()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint())
				break;
			Transform2D xf;
			xf.rotate(cast_to.angle());
			xf.translate(Vector2(cast_to.length(), 0));

			//Vector2 tip = Vector2(0,s->get_length());
			Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
			draw_line(Vector2(), cast_to, dcol, 3);
			Vector<Vector2> pts;
			float tsize = 4;
			pts.push_back(xf.xform(Vector2(tsize, 0)));
			pts.push_back(xf.xform(Vector2(0, 0.707 * tsize)));
			pts.push_back(xf.xform(Vector2(0, -0.707 * tsize)));
			Vector<Color> cols;
			for (int i = 0; i < 3; i++)
				cols.push_back(dcol);

			draw_primitive(pts, cols, Vector<Vector2>()); //small arrow

		} break;

		case NOTIFICATION_FIXED_PROCESS: {

			if (!enabled)
				break;

			_update_raycast_state();

		} break;
	}
}