void AnimationTree::_process_graph(float p_delta) {

	_update_properties(); //if properties need updating, update them

	//check all tracks, see if they need modification

	root_motion_transform = Transform();

	if (!root.is_valid()) {
		ERR_PRINT("AnimationTree: root AnimationNode is not set, disabling playback.");
		set_active(false);
		cache_valid = false;
		return;
	}

	if (!has_node(animation_player)) {
		ERR_PRINT("AnimationTree: no valid AnimationPlayer path set, disabling playback");
		set_active(false);
		cache_valid = false;
		return;
	}

	AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));

	ObjectID current_animation_player = 0;

	if (player) {
		current_animation_player = player->get_instance_id();
	}

	if (last_animation_player != current_animation_player) {

		if (last_animation_player) {
			Object *old_player = ObjectDB::get_instance(last_animation_player);
			if (old_player) {
				old_player->disconnect("caches_cleared", this, "_clear_caches");
			}
		}

		if (player) {
			player->connect("caches_cleared", this, "_clear_caches");
		}

		last_animation_player = current_animation_player;
	}

	if (!player) {
		ERR_PRINT("AnimationTree: path points to a node not an AnimationPlayer, disabling playback");
		set_active(false);
		cache_valid = false;
		return;
	}

	if (!cache_valid) {
		if (!_update_caches(player)) {
			return;
		}
	}

	{ //setup

		process_pass++;

		state.valid = true;
		state.invalid_reasons = "";
		state.animation_states.clear(); //will need to be re-created
		state.valid = true;
		state.player = player;
		state.last_pass = process_pass;
		state.tree = this;

		// root source blends

		root->blends.resize(state.track_count);
		float *src_blendsw = root->blends.ptrw();
		for (int i = 0; i < state.track_count; i++) {
			src_blendsw[i] = 1.0; //by default all go to 1 for the root input
		}
	}

	//process

	{

		if (started) {
			//if started, seek
			root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, NULL, &state, 0, true, Vector<StringName>());
			started = false;
		}

		root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, NULL, &state, p_delta, false, Vector<StringName>());
	}

	if (!state.valid) {
		return; //state is not valid. do nothing.
	}
	//apply value/transform/bezier blends to track caches and execute method/audio/animation tracks

	{

		bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();

		for (List<AnimationNode::AnimationState>::Element *E = state.animation_states.front(); E; E = E->next()) {

			const AnimationNode::AnimationState &as = E->get();

			Ref<Animation> a = as.animation;
			float time = as.time;
			float delta = as.delta;
			bool seeked = as.seeked;

			for (int i = 0; i < a->get_track_count(); i++) {

				NodePath path = a->track_get_path(i);
				TrackCache *track = track_cache[path];
				if (track->type != a->track_get_type(i)) {
					continue; //may happen should not
				}

				track->root_motion = root_motion_track == path;

				ERR_CONTINUE(!state.track_map.has(path));
				int blend_idx = state.track_map[path];

				ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count);

				float blend = (*as.track_blends)[blend_idx];

				if (blend < CMP_EPSILON)
					continue; //nothing to blend

				switch (track->type) {

					case Animation::TYPE_TRANSFORM: {

						TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);

						if (t->process_pass != process_pass) {

							t->process_pass = process_pass;
							t->loc = Vector3();
							t->rot = Quat();
							t->rot_blend_accum = 0;
							t->scale = Vector3();
						}

						if (track->root_motion) {

							float prev_time = time - delta;
							if (prev_time < 0) {
								if (!a->has_loop()) {
									prev_time = 0;
								} else {
									prev_time = a->get_length() + prev_time;
								}
							}

							Vector3 loc[2];
							Quat rot[2];
							Vector3 scale[2];

							if (prev_time > time) {

								Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]);
								if (err != OK) {
									continue;
								}

								a->transform_track_interpolate(i, a->get_length(), &loc[1], &rot[1], &scale[1]);

								t->loc += (loc[1] - loc[0]) * blend;
								t->scale += (scale[1] - scale[0]) * blend;
								Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
								t->rot = (t->rot * q).normalized();

								prev_time = 0;
							}

							Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]);
							if (err != OK) {
								continue;
							}

							a->transform_track_interpolate(i, time, &loc[1], &rot[1], &scale[1]);

							t->loc += (loc[1] - loc[0]) * blend;
							t->scale += (scale[1] - scale[0]) * blend;
							Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
							t->rot = (t->rot * q).normalized();

							prev_time = 0;

						} else {
							Vector3 loc;
							Quat rot;
							Vector3 scale;

							Error err = a->transform_track_interpolate(i, time, &loc, &rot, &scale);
							//ERR_CONTINUE(err!=OK); //used for testing, should be removed

							scale -= Vector3(1.0, 1.0, 1.0); //helps make it work properly with Add nodes

							if (err != OK)
								continue;

							t->loc = t->loc.linear_interpolate(loc, blend);
							if (t->rot_blend_accum == 0) {
								t->rot = rot;
								t->rot_blend_accum = blend;
							} else {
								float rot_total = t->rot_blend_accum + blend;
								t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized();
								t->rot_blend_accum = rot_total;
							}
							t->scale = t->scale.linear_interpolate(scale, blend);
						}

					} break;
					case Animation::TYPE_VALUE: {

						TrackCacheValue *t = static_cast<TrackCacheValue *>(track);

						Animation::UpdateMode update_mode = a->value_track_get_update_mode(i);

						if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE) { //delta == 0 means seek

							Variant value = a->value_track_interpolate(i, time);

							if (value == Variant())
								continue;

							if (t->process_pass != process_pass) {
								Variant::CallError ce;
								t->value = Variant::construct(value.get_type(), NULL, 0, ce); //reset
								t->process_pass = process_pass;
							}

							Variant::interpolate(t->value, value, blend, t->value);

						} else if (delta != 0) {

							List<int> indices;
							a->value_track_get_key_indices(i, time, delta, &indices);

							for (List<int>::Element *F = indices.front(); F; F = F->next()) {

								Variant value = a->track_get_key_value(i, F->get());
								t->object->set_indexed(t->subpath, value);
							}
						}

					} break;
					case Animation::TYPE_METHOD: {

						if (delta == 0) {
							continue;
						}
						TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);

						List<int> indices;

						a->method_track_get_key_indices(i, time, delta, &indices);

						for (List<int>::Element *E = indices.front(); E; E = E->next()) {

							StringName method = a->method_track_get_name(i, E->get());
							Vector<Variant> params = a->method_track_get_params(i, E->get());

							int s = params.size();

							ERR_CONTINUE(s > VARIANT_ARG_MAX);
							if (can_call) {
								t->object->call_deferred(
										method,
										s >= 1 ? params[0] : Variant(),
										s >= 2 ? params[1] : Variant(),
										s >= 3 ? params[2] : Variant(),
										s >= 4 ? params[3] : Variant(),
										s >= 5 ? params[4] : Variant());
							}
						}

					} break;
					case Animation::TYPE_BEZIER: {

						TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);

						float bezier = a->bezier_track_interpolate(i, time);

						if (t->process_pass != process_pass) {
							t->value = 0;
							t->process_pass = process_pass;
						}

						t->value = Math::lerp(t->value, bezier, blend);

					} break;
					case Animation::TYPE_AUDIO: {

						TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);

						if (seeked) {
							//find whathever should be playing
							int idx = a->track_find_key(i, time);
							if (idx < 0)
								continue;

							Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
							if (!stream.is_valid()) {
								t->object->call("stop");
								t->playing = false;
								playing_caches.erase(t);
							} else {
								float start_ofs = a->audio_track_get_key_start_offset(i, idx);
								start_ofs += time - a->track_get_key_time(i, idx);
								float end_ofs = a->audio_track_get_key_end_offset(i, idx);
								float len = stream->get_length();

								if (start_ofs > len - end_ofs) {
									t->object->call("stop");
									t->playing = false;
									playing_caches.erase(t);
									continue;
								}

								t->object->call("set_stream", stream);
								t->object->call("play", start_ofs);

								t->playing = true;
								playing_caches.insert(t);
								if (len && end_ofs > 0) { //force a end at a time
									t->len = len - start_ofs - end_ofs;
								} else {
									t->len = 0;
								}

								t->start = time;
							}

						} else {
							//find stuff to play
							List<int> to_play;
							a->track_get_key_indices_in_range(i, time, delta, &to_play);
							if (to_play.size()) {
								int idx = to_play.back()->get();

								Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
								if (!stream.is_valid()) {
									t->object->call("stop");
									t->playing = false;
									playing_caches.erase(t);
								} else {
									float start_ofs = a->audio_track_get_key_start_offset(i, idx);
									float end_ofs = a->audio_track_get_key_end_offset(i, idx);
									float len = stream->get_length();

									t->object->call("set_stream", stream);
									t->object->call("play", start_ofs);

									t->playing = true;
									playing_caches.insert(t);
									if (len && end_ofs > 0) { //force a end at a time
										t->len = len - start_ofs - end_ofs;
									} else {
										t->len = 0;
									}

									t->start = time;
								}
							} else if (t->playing) {

								bool loop = a->has_loop();

								bool stop = false;

								if (!loop && time < t->start) {
									stop = true;
								} else if (t->len > 0) {
									float len = t->start > time ? (a->get_length() - t->start) + time : time - t->start;

									if (len > t->len) {
										stop = true;
									}
								}

								if (stop) {
									//time to stop
									t->object->call("stop");
									t->playing = false;
									playing_caches.erase(t);
								}
							}
						}

						float db = Math::linear2db(MAX(blend, 0.00001));
						if (t->object->has_method("set_unit_db")) {
							t->object->call("set_unit_db", db);
						} else {
							t->object->call("set_volume_db", db);
						}
					} break;
					case Animation::TYPE_ANIMATION: {

						TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track);

						AnimationPlayer *player = Object::cast_to<AnimationPlayer>(t->object);

						if (!player)
							continue;

						if (delta == 0 || seeked) {
							//seek
							int idx = a->track_find_key(i, time);
							if (idx < 0)
								continue;

							float pos = a->track_get_key_time(i, idx);

							StringName anim_name = a->animation_track_get_key_animation(i, idx);
							if (String(anim_name) == "[stop]" || !player->has_animation(anim_name))
								continue;

							Ref<Animation> anim = player->get_animation(anim_name);

							float at_anim_pos;

							if (anim->has_loop()) {
								at_anim_pos = Math::fposmod(time - pos, anim->get_length()); //seek to loop
							} else {
								at_anim_pos = MAX(anim->get_length(), time - pos); //seek to end
							}

							if (player->is_playing() || seeked) {
								player->play(anim_name);
								player->seek(at_anim_pos);
								t->playing = true;
								playing_caches.insert(t);
							} else {
								player->set_assigned_animation(anim_name);
								player->seek(at_anim_pos, true);
							}
						} else {
							//find stuff to play
							List<int> to_play;
							a->track_get_key_indices_in_range(i, time, delta, &to_play);
							if (to_play.size()) {
								int idx = to_play.back()->get();

								StringName anim_name = a->animation_track_get_key_animation(i, idx);
								if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) {

									if (playing_caches.has(t)) {
										playing_caches.erase(t);
										player->stop();
										t->playing = false;
									}
								} else {
									player->play(anim_name);
									t->playing = true;
									playing_caches.insert(t);
								}
							}
						}

					} break;
				}
			}
		}
	}

	{
		// finally, set the tracks
		const NodePath *K = NULL;
		while ((K = track_cache.next(K))) {
			TrackCache *track = track_cache[*K];
			if (track->process_pass != process_pass)
				continue; //not processed, ignore

			switch (track->type) {

				case Animation::TYPE_TRANSFORM: {

					TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);

					Transform xform;
					xform.origin = t->loc;

					t->scale += Vector3(1.0, 1.0, 1.0); //helps make it work properly with Add nodes and root motion

					xform.basis.set_quat_scale(t->rot, t->scale);

					if (t->root_motion) {

						root_motion_transform = xform;

						if (t->skeleton && t->bone_idx >= 0) {
							root_motion_transform = (t->skeleton->get_bone_rest(t->bone_idx) * root_motion_transform) * t->skeleton->get_bone_rest(t->bone_idx).affine_inverse();
						}
					} else if (t->skeleton && t->bone_idx >= 0) {

						t->skeleton->set_bone_pose(t->bone_idx, xform);

					} else {

						t->spatial->set_transform(xform);
					}

				} break;
				case Animation::TYPE_VALUE: {

					TrackCacheValue *t = static_cast<TrackCacheValue *>(track);

					t->object->set_indexed(t->subpath, t->value);

				} break;
				case Animation::TYPE_BEZIER: {

					TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);

					t->object->set_indexed(t->subpath, t->value);

				} break;
				default: {} //the rest don't matter
			}
		}
	}
}
bool BodyPairSW::setup(float p_step) {

	//cannot collide
	if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) {
		collided=false;
		return false;
	}

	offset_B = B->get_transform().get_origin() - A->get_transform().get_origin();

	validate_contacts();

	Vector3 offset_A = A->get_transform().get_origin();
	Transform xform_Au = Transform(A->get_transform().basis,Vector3());
	Transform xform_A = xform_Au * A->get_shape_transform(shape_A);

	Transform xform_Bu = B->get_transform();
	xform_Bu.origin-=offset_A;
	Transform xform_B = xform_Bu * B->get_shape_transform(shape_B);

	ShapeSW *shape_A_ptr=A->get_shape(shape_A);
	ShapeSW *shape_B_ptr=B->get_shape(shape_B);

	bool collided = CollisionSolverSW::solve_static(shape_A_ptr,xform_A,shape_B_ptr,xform_B,_contact_added_callback,this,&sep_axis);
	this->collided=collided;


	if (!collided) {

		//test ccd (currently just a raycast)

		if (A->is_continuous_collision_detection_enabled() && A->get_mode()>PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC) {
			_test_ccd(p_step,A,shape_A,xform_A,B,shape_B,xform_B);
		}

		if (B->is_continuous_collision_detection_enabled() && B->get_mode()>PhysicsServer::BODY_MODE_KINEMATIC && A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC) {
			_test_ccd(p_step,B,shape_B,xform_B,A,shape_A,xform_A);
		}

		return false;
	}



	real_t max_penetration = space->get_contact_max_allowed_penetration();

	float bias = 0.3f;

	if (shape_A_ptr->get_custom_bias() || shape_B_ptr->get_custom_bias()) {

		if (shape_A_ptr->get_custom_bias()==0)
			bias=shape_B_ptr->get_custom_bias();
		else if (shape_B_ptr->get_custom_bias()==0)
			bias=shape_A_ptr->get_custom_bias();
		else
			bias=(shape_B_ptr->get_custom_bias()+shape_A_ptr->get_custom_bias())*0.5;
	}



	real_t inv_dt = 1.0/p_step;

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

		Contact &c = contacts[i];
		c.active=false;

		Vector3 global_A = xform_Au.xform(c.local_A);
		Vector3 global_B = xform_Bu.xform(c.local_B);


		real_t depth = c.normal.dot(global_A - global_B);

		if (depth<=0) {
			c.active=false;
			continue;
		}

		c.active=true;

#ifdef DEBUG_ENABLED


		if (space->is_debugging_contacts()) {
			space->add_debug_contact(global_A+offset_A);
			space->add_debug_contact(global_B+offset_A);
		}
#endif


		int gather_A = A->can_report_contacts();
		int gather_B = B->can_report_contacts();

		c.rA = global_A;
		c.rB = global_B-offset_B;

		// contact query reporting...
#if 0
		if (A->get_body_type() == PhysicsServer::BODY_CHARACTER)
			static_cast<CharacterBodySW*>(A)->report_character_contact( global_A, global_B, B );
		if (B->get_body_type() == PhysicsServer::BODY_CHARACTER)
			static_cast<CharacterBodySW*>(B)->report_character_contact( global_B, global_A, A );
		if (A->has_contact_query())
			A->report_contact( global_A, global_B, B );
		if (B->has_contact_query())
			B->report_contact( global_B, global_A, A );
#endif

		if (A->can_report_contacts()) {
			Vector3 crB = A->get_angular_velocity().cross( c.rA ) + A->get_linear_velocity();
			A->add_contact(global_A,-c.normal,depth,shape_A,global_B,shape_B,B->get_instance_id(),B->get_self(),crB);
		}

		if (B->can_report_contacts()) {
			Vector3 crA = A->get_angular_velocity().cross( c.rB ) + A->get_linear_velocity();
			B->add_contact(global_B,c.normal,depth,shape_B,global_A,shape_A,A->get_instance_id(),A->get_self(),crA);
		}

		if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC)) {
			c.active=false;
			collided=false;
			continue;

		}


		c.active=true;

		// Precompute normal mass, tangent mass, and bias.
		Vector3 inertia_A = A->get_inv_inertia_tensor().xform( c.rA.cross( c.normal ) );
		Vector3 inertia_B = B->get_inv_inertia_tensor().xform( c.rB.cross( c.normal ) );
		real_t kNormal = A->get_inv_mass() + B->get_inv_mass();
		kNormal += c.normal.dot( inertia_A.cross(c.rA ) ) + c.normal.dot( inertia_B.cross( c.rB ));
		c.mass_normal = 1.0f / kNormal;

#if 1
		c.bias = -bias * inv_dt * MIN(0.0f, -depth + max_penetration);

#else
		if (depth > max_penetration) {
			c.bias = (depth - max_penetration) * (1.0/(p_step*(1.0/RELAXATION_TIMESTEPS)));
		} else {
			float approach = -0.1f * (depth - max_penetration) / (CMP_EPSILON + max_penetration);
			approach = CLAMP( approach, CMP_EPSILON, 1.0 );
			c.bias = approach * (depth - max_penetration) * (1.0/p_step);
		}
#endif
		c.depth=depth;

		Vector3 j_vec = c.normal * c.acc_normal_impulse + c.acc_tangent_impulse;
		A->apply_impulse( c.rA, -j_vec );
		B->apply_impulse( c.rB, j_vec );
		c.acc_bias_impulse=0;
		Vector3 jb_vec = c.normal * c.acc_bias_impulse;
		A->apply_bias_impulse( c.rA, -jb_vec );
		B->apply_bias_impulse( c.rB, jb_vec );

		c.bounce = MAX(A->get_bounce(),B->get_bounce());
		if (c.bounce) {

			Vector3 crA = A->get_angular_velocity().cross( c.rA );
			Vector3 crB = B->get_angular_velocity().cross( c.rB );
			Vector3 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA;
			//normal impule
			c.bounce = c.bounce * dv.dot(c.normal);
		}


	}

	return true;
}
void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
    assert(renderContext->getArgs());
    assert(renderContext->getArgs()->_viewFrustum);

    RenderArgs* args = renderContext->getArgs();
    gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
        auto framebufferCache = DependencyManager::get<FramebufferCache>();
        QSize framebufferSize = framebufferCache->getFrameBufferSize();
        float fbWidth = framebufferSize.width();
        float fbHeight = framebufferSize.height();
        float sMin = args->_viewport.x / fbWidth;
        float sWidth = args->_viewport.z / fbWidth;
        float tMin = args->_viewport.y / fbHeight;
        float tHeight = args->_viewport.w / fbHeight;


        glm::mat4 projMat;
        Transform viewMat;
        args->_viewFrustum->evalProjectionMatrix(projMat);
        args->_viewFrustum->evalViewTransform(viewMat);
        batch.setProjectionTransform(projMat);
        batch.setViewTransform(viewMat);
        batch.setModelTransform(Transform());

        // Occlusion step
        getOcclusionPipeline();
        batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture());
        batch.setResourceTexture(1, framebufferCache->getDeferredNormalTexture());
        _occlusionBuffer->setRenderBuffer(0, _occlusionTexture);
        batch.setFramebuffer(_occlusionBuffer);

        // Occlusion uniforms
        g_scale = 1.0f;
        g_bias = 1.0f;
        g_sample_rad = 1.0f;
        g_intensity = 1.0f;

        // Bind the first gpu::Pipeline we need - for calculating occlusion buffer
        batch.setPipeline(getOcclusionPipeline());
        batch._glUniform1f(_gScaleLoc, g_scale);
        batch._glUniform1f(_gBiasLoc, g_bias);
        batch._glUniform1f(_gSampleRadiusLoc, g_sample_rad);
        batch._glUniform1f(_gIntensityLoc, g_intensity);

        // setup uniforms for unpacking a view-space position from the depth buffer
        // This is code taken from DeferredLightEffect.render() method in DeferredLightingEffect.cpp.
        // DeferredBuffer.slh shows how the unpacking is done and what variables are needed.

        // initialize the view-space unpacking uniforms using frustum data
        float left, right, bottom, top, nearVal, farVal;
        glm::vec4 nearClipPlane, farClipPlane;

        args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);

        float depthScale = (farVal - nearVal) / farVal;
        float nearScale = -1.0f / nearVal;
        float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
        float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
        float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
        float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;

        // now set the position-unpacking unforms
        batch._glUniform1f(_nearLoc, nearVal);
        batch._glUniform1f(_depthScaleLoc, depthScale);
        batch._glUniform2f(_depthTexCoordOffsetLoc, depthTexCoordOffsetS, depthTexCoordOffsetT);
        batch._glUniform2f(_depthTexCoordScaleLoc, depthTexCoordScaleS, depthTexCoordScaleT);

        batch._glUniform2f(_renderTargetResLoc, fbWidth, fbHeight);
        batch._glUniform2f(_renderTargetResInvLoc, 1.0f / fbWidth, 1.0f / fbHeight);

        glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
        glm::vec2 bottomLeft(-1.0f, -1.0f);
        glm::vec2 topRight(1.0f, 1.0f);
        glm::vec2 texCoordTopLeft(0.0f, 0.0f);
        glm::vec2 texCoordBottomRight(1.0f, 1.0f);
        DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);

        // Vertical blur step
        getVBlurPipeline();
        batch.setResourceTexture(0, _occlusionTexture);
        _vBlurBuffer->setRenderBuffer(0, _vBlurTexture);
        batch.setFramebuffer(_vBlurBuffer);

        // Bind the second gpu::Pipeline we need - for calculating blur buffer
        batch.setPipeline(getVBlurPipeline());

        DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);

        // Horizontal blur step
        getHBlurPipeline();
        batch.setResourceTexture(0, _vBlurTexture);
        _hBlurBuffer->setRenderBuffer(0, _hBlurTexture);
        batch.setFramebuffer(_hBlurBuffer);

        // Bind the third gpu::Pipeline we need - for calculating blur buffer
        batch.setPipeline(getHBlurPipeline());

        DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);

        // Blend step
        getBlendPipeline();
        batch.setResourceTexture(0, _hBlurTexture);
        batch.setFramebuffer(framebufferCache->getDeferredFramebuffer());

        // Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture
        batch.setPipeline(getBlendPipeline());

        DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
    });
}
Exemple #4
0
void LightSource::Scale(const Vector3d&, const TRANSFORM *tr)
{
    Transform(tr);
}
Exemple #5
0
void
APITestUtil::CombinedTests()
{
	// now let's build a test object
	NURBSSet nset;
	Matrix3 mat;
	mat.IdentityMatrix();


	// build an independent point
	int indPnt = MakeTestPoint(nset);

	// now a constrained point
	int ptPnt = MakeTestPointCPoint(nset, indPnt);



	// build a cv curve
	int cvCrv = MakeTestCVCurve(nset, mat);

	// and a constrained point on that curve
	int crvPnt = MakeTestCurveCPoint(nset, cvCrv);

	// now a point curve
	int ptCrv = MakeTestPointCurve(nset, mat);

	// Blend the two curves
	int blendCrv = MakeTestBlendCurve(nset, cvCrv, ptCrv);

	// make an offset of the CV curve
	int offCrv = MakeTestOffsetCurve(nset, cvCrv);

	// make a Transform curve of the point curve
	int xformCrv = MakeTestXFormCurve(nset, ptCrv);

	// make a mirror of the blend
	int mirCrv = MakeTestMirrorCurve(nset, blendCrv);

	// make a fillet curve (It makes it's own point curves to fillet)
	int fltCrv = MakeTestFilletCurve(nset);

	// make a chamfer curve (It makes it's own point curves to fillet)
	int chmCrv = MakeTestChamferCurve(nset);




	// build a cv surface
	int cvSurf = MakeTestCVSurface(nset, mat);


	// and a constrained point on that surface
	int srfPnt = MakeTestSurfCPoint(nset, cvSurf);

	// Curve Surface intersection point.
	int cvCrv2 = MakeTestCVCurve(nset, RotateXMatrix(PI/2.0f) * TransMatrix(Point3(0, 0, -175)));
	int srfIntPoint = MakeTestCurveSurface(nset, cvSurf, cvCrv2);

	// Now an Iso Curve on the CV surface
	int isoCrv1 = MakeTestIsoCurveU(nset, cvSurf);

	// Now an Iso Curve on the CV surface
	int isoCrv2 = MakeTestIsoCurveV(nset, cvSurf);

	// Now a Surface Edge Curve on the CV surface
	int surfEdgeCrv = MakeTestSurfaceEdgeCurve(nset, cvSurf);

	// build a CV Curve on Surface
	int cvCOS = MakeTestCurveOnSurface(nset, cvSurf);

	// build a Point Curve on Surface
	int pntCOS = MakeTestPointCurveOnSurface(nset, cvSurf);

	// build a Surface Normal Offset Curve
	int cnoCrf = MakeTestSurfaceNormalCurve(nset, cvCOS);

    // Make a curve-curve intersection point
    int curveCurve = MakeTestCurveCurve(nset, isoCrv1, isoCrv2, TRUE);

	// build a point surface
	int ptSurf = MakeTestPointSurface(nset, mat);

	// Blend the two surfaces
	int blendSurf = MakeTestBlendSurface(nset, cvSurf, ptSurf);

	// Offset of the blend
	int offSurf = MakeTestOffsetSurface(nset, blendSurf);

	// Transform of the Offset
	int xformSurf = MakeTestXFormSurface(nset, offSurf);

	// Mirror of the transform surface
	int mirSurf = MakeTestMirrorSurface(nset, xformSurf);

	// Make a Ruled surface between two curves
	int rulSurf = MakeTestRuledSurface(nset, cvCrv, ptCrv);

	// Make a ULoft surface
	int uLoftSurf = MakeTestULoftSurface(nset, ptCrv, offCrv, xformCrv);

	// Make a Extrude surface
	int extSurf = MakeTestExtrudeSurface(nset, xformCrv);

	// Make a lathe
	int lthSurf = MakeTestLatheSurface(nset);

	// these will build their own curves to work with
	// UV Loft
	int uvLoftSurf = MakeTestUVLoftSurface(nset);


	// 1 Rail Sweep
	int oneRailSurf = MakeTest1RailSweepSurface(nset);

	// 2 Rail Sweep
	int twoRailSurf = MakeTest2RailSweepSurface(nset);

	// MultiCurveTrim Surface
	int multiTrimSurf = MakeTestMultiCurveTrimSurface(nset);


	// Now make the curves and surfaces that we'll use later for the join tests
	int jc1, jc2, js1, js2;
	AddObjectsForJoinTests(nset, jc1, jc2, js1, js2);

	int bc, bs;
	AddObjectsForBreakTests(nset, bc, bs);


	Object *obj = CreateNURBSObject(mpIp, &nset, mat);
	INode *node = mpIp->CreateObjectNode(obj);
	node->SetName(GetString(IDS_TEST_OBJECT));




	NURBSSet addNset;
	// build a point surface
	int addptSurf = AddTestPointSurface(addNset);

	// add an iso curve to the previously created CV Surface
	NURBSId id = nset.GetNURBSObject(cvSurf)->GetId();
	int addIsoCrv = AddTestIsoCurve(addNset, id);

	AddNURBSObjects(obj, mpIp, &addNset);




	// now test some changing functionality
	// Let's change the name of the CVSurface
	NURBSObject* nObj = nset.GetNURBSObject(cvSurf);
	nObj->SetName(_T("New CVSurf Name"));  // testing only, no need to localize

	// now let's change the position of one of the points in the point curve
	NURBSPointCurve* ptCrvObj = (NURBSPointCurve*)nset.GetNURBSObject(ptCrv);
	ptCrvObj->GetPoint(0)->SetPosition(0, Point3(10, 160, 0)); // moved from 0,150,0

	// now let's change the position and weight of one of the CVs
	// in the CV Surface
	NURBSCVSurface* cvSurfObj = (NURBSCVSurface*)nset.GetNURBSObject(cvSurf);
	cvSurfObj->GetCV(0, 0)->SetPosition(0, Point3(-150.0, -100.0, 20.0)); // moved from 0,0,0
	cvSurfObj->GetCV(0, 0)->SetWeight(0, 2.0); // from 1.0


	// now let's do a transform of a curve.
	NURBSIdTab xfmTab;
	NURBSId nid = nset.GetNURBSObject(jc1)->GetId();
	xfmTab.Append(1, &nid);
	Matrix3 xfmMat;
	xfmMat = TransMatrix(Point3(10, 10, -10));
	SetXFormPacket xPack(xfmMat);
	NURBSResult res = Transform(obj, xfmTab, xPack, xfmMat, 0);




	// Now let's Join two curves
	NURBSId jc1id = nset.GetNURBSObject(jc1)->GetId(),
			jc2id = nset.GetNURBSObject(jc2)->GetId();
	JoinCurves(obj, jc1id, jc2id, FALSE, TRUE, 20.0, 1.0f, 1.0f, 0);

	// Now let's Join two surfaces
	NURBSId js1id = nset.GetNURBSObject(js1)->GetId(),
			js2id = nset.GetNURBSObject(js2)->GetId();
	JoinSurfaces(obj, js1id, js2id, 1, 0, 20.0, 1.0f, 1.0f, 0);

	// Break a Curve
	NURBSId bcid = nset.GetNURBSObject(bc)->GetId();
	BreakCurve(obj, bcid, .5, 0);

	// Break a Surface
	NURBSId bsid = nset.GetNURBSObject(bs)->GetId();
	BreakSurface(obj, bsid, TRUE, .5, 0);

	mpIp->RedrawViews(mpIp->GetTime());
	nset.DeleteObjects();
	addNset.DeleteObjects();


	// now do a detach
	NURBSSet detset;
	Matrix3 detmat;
	detmat.IdentityMatrix();
	// build a cv curve
	int detcvCrv = MakeTestCVCurve(detset, detmat);

	// now a point curve
	int detptCrv = MakeTestPointCurve(detset, detmat);

	// Blend the two curves
	int detblendCrv = MakeTestBlendCurve(detset, detcvCrv, detptCrv);

	Object *detobj = CreateNURBSObject(mpIp, &detset, detmat);
	INode *detnode = mpIp->CreateObjectNode(detobj);
	detnode->SetName("Detach From");

	BOOL copy = TRUE;
	BOOL relational = TRUE;
	NURBSIdList detlist;
	NURBSId oid = detset.GetNURBSObject(detblendCrv)->GetId();
	detlist.Append(1, &oid);
	DetachObjects(GetCOREInterface()->GetTime(), detnode, detobj,
					detlist, "Detach Test", copy, relational);
	mpIp->RedrawViews(mpIp->GetTime());

}
void
BasicCompositor::DrawQuad(const gfx::Rect& aRect,
                          const gfx::Rect& aClipRect,
                          const EffectChain &aEffectChain,
                          gfx::Float aOpacity,
                          const gfx::Matrix4x4& aTransform,
                          const gfx::Rect& aVisibleRect)
{
  RefPtr<DrawTarget> buffer = mRenderTarget->mDrawTarget;

  // For 2D drawing, |dest| and |buffer| are the same surface. For 3D drawing,
  // |dest| is a temporary surface.
  RefPtr<DrawTarget> dest = buffer;

  buffer->PushClipRect(aClipRect);
  AutoRestoreTransform autoRestoreTransform(dest);

  Matrix newTransform;
  Rect transformBounds;
  Matrix4x4 new3DTransform;
  IntPoint offset = mRenderTarget->GetOrigin();

  if (aTransform.Is2D()) {
    newTransform = aTransform.As2D();
  } else {
    // Create a temporary surface for the transform.
    dest = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(RoundOut(aRect).Size(), SurfaceFormat::B8G8R8A8);
    if (!dest) {
      return;
    }

    dest->SetTransform(Matrix::Translation(-aRect.x, -aRect.y));

    // Get the bounds post-transform.
    transformBounds = aTransform.TransformAndClipBounds(aRect, Rect(offset.x, offset.y, buffer->GetSize().width, buffer->GetSize().height));
    transformBounds.RoundOut();

    // Propagate the coordinate offset to our 2D draw target.
    newTransform = Matrix::Translation(transformBounds.x, transformBounds.y);

    // When we apply the 3D transformation, we do it against a temporary
    // surface, so undo the coordinate offset.
    new3DTransform = Matrix4x4::Translation(aRect.x, aRect.y, 0) * aTransform;
  }

  newTransform.PostTranslate(-offset.x, -offset.y);
  buffer->SetTransform(newTransform);

  RefPtr<SourceSurface> sourceMask;
  Matrix maskTransform;
  if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) {
    EffectMask *effectMask = static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EffectTypes::MASK].get());
    sourceMask = effectMask->mMaskTexture->AsSourceBasic()->GetSurface(dest);
    MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!");
    MOZ_ASSERT(!effectMask->mIs3D);
    maskTransform = effectMask->mMaskTransform.As2D();
    maskTransform.PreTranslate(-offset.x, -offset.y);
  }

  CompositionOp blendMode = CompositionOp::OP_OVER;
  if (Effect* effect = aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get()) {
    blendMode = static_cast<EffectBlendMode*>(effect)->mBlendMode;
  }

  switch (aEffectChain.mPrimaryEffect->mType) {
    case EffectTypes::SOLID_COLOR: {
      EffectSolidColor* effectSolidColor =
        static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get());

      FillRectWithMask(dest, aRect, effectSolidColor->mColor,
                       DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform);
      break;
    }
    case EffectTypes::RGB: {
      TexturedEffect* texturedEffect =
          static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
      TextureSourceBasic* source = texturedEffect->mTexture->AsSourceBasic();

      if (texturedEffect->mPremultiplied) {
          DrawSurfaceWithTextureCoords(dest, aRect,
                                       source->GetSurface(dest),
                                       texturedEffect->mTextureCoords,
                                       texturedEffect->mFilter,
                                       DrawOptions(aOpacity, blendMode),
                                       sourceMask, &maskTransform);
      } else {
          RefPtr<DataSourceSurface> srcData = source->GetSurface(dest)->GetDataSurface();

          // Yes, we re-create the premultiplied data every time.
          // This might be better with a cache, eventually.
          RefPtr<DataSourceSurface> premultData = gfxUtils::CreatePremultipliedDataSurface(srcData);

          DrawSurfaceWithTextureCoords(dest, aRect,
                                       premultData,
                                       texturedEffect->mTextureCoords,
                                       texturedEffect->mFilter,
                                       DrawOptions(aOpacity, blendMode),
                                       sourceMask, &maskTransform);
      }
      break;
    }
    case EffectTypes::YCBCR: {
      NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!");
      break;
    }
    case EffectTypes::RENDER_TARGET: {
      EffectRenderTarget* effectRenderTarget =
        static_cast<EffectRenderTarget*>(aEffectChain.mPrimaryEffect.get());
      RefPtr<BasicCompositingRenderTarget> surface
        = static_cast<BasicCompositingRenderTarget*>(effectRenderTarget->mRenderTarget.get());
      RefPtr<SourceSurface> sourceSurf = surface->mDrawTarget->Snapshot();

      DrawSurfaceWithTextureCoords(dest, aRect,
                                   sourceSurf,
                                   effectRenderTarget->mTextureCoords,
                                   effectRenderTarget->mFilter,
                                   DrawOptions(aOpacity, blendMode),
                                   sourceMask, &maskTransform);
      break;
    }
    case EffectTypes::COMPONENT_ALPHA: {
      NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!");
      break;
    }
    default: {
      NS_RUNTIMEABORT("Invalid effect type!");
      break;
    }
  }

  if (!aTransform.Is2D()) {
    dest->Flush();

    RefPtr<SourceSurface> snapshot = dest->Snapshot();
    RefPtr<DataSourceSurface> source = snapshot->GetDataSurface();
    RefPtr<DataSourceSurface> temp =
      Factory::CreateDataSourceSurface(RoundOut(transformBounds).Size(), SurfaceFormat::B8G8R8A8
#ifdef MOZ_ENABLE_SKIA
        , true
#endif
        );
    if (NS_WARN_IF(!temp)) {
      buffer->PopClip();
      return;
    }

    Transform(temp, source, new3DTransform, transformBounds.TopLeft());

    transformBounds.MoveTo(0, 0);
    buffer->DrawSurface(temp, transformBounds, transformBounds);
  }

  buffer->PopClip();
}
Exemple #7
0
void Plane::Transform(const Quat &transform)
{
    float3x3 r = transform.ToFloat3x3();
    Transform(r);
}
Exemple #8
0
 Cone& Cone::Transform(const NX::Matrix<float, 3, 3> &R, const NX::vector<float, 3>    &T){
     return Transform(NX::GetRTMatrix(R, T));
 }
Exemple #9
0
 Cone& Cone::Transform(const NX::vector<float, 3>    &T, const NX::Matrix<float, 3, 3> &R){
     return Transform(NX::GetTRMatrix(T, R));
 }
Exemple #10
0
 Cone::Cone(const float fLongAxis, const float fShortAxis, const float fHeight, const NX::Matrix<float, 4, 4> &M):m_vCenter(0.0f, 0.0f, 0.0f), m_vNormal(0.0f, 1.0f, 0.0f), m_vLongAxis(1.0f, 0.0f, 0.0f), m_vShortAxis(0.0f, 0.0f, 1.0f){
     m_fLongAxis   = fLongAxis;
     m_fShortAxis  = fShortAxis;
     m_fHeight     = fHeight;
     Transform(M);
 }
Exemple #11
0
 Cone::Cone(const float fLongAxis, const float fShortAxis, const float fHeight, const NX::vector<float, 3> &T, const NX::Matrix<float, 3, 3> &R):m_vCenter(0.0f, 0.0f, 0.0f), m_vNormal(0.0f, 1.0f, 0.0f), m_vLongAxis(1.0f, 0.0f, 0.0f), m_vShortAxis(0.0f, 0.0f, 1.0f){
     m_fLongAxis   = fLongAxis;
     m_fShortAxis  = fShortAxis;
     m_fHeight     = fHeight;
     Transform(T, R);
 }
void GrassBlendingGame::Initialize()
{
    window->SetTitle("TestApp - Enjoy Game Dev, Have Fun.");
    window->SetAllowUserResizing(true);

    auto assets = gameHost->AssetManager();
    auto clientBounds = window->GetClientBounds();

    {
        commandList = std::make_shared<GraphicsCommandList>(*graphicsDevice);

        samplerPoint = std::make_shared<SamplerState>(graphicsDevice,
            SamplerDescription::CreateLinearWrap());

        texture = std::make_shared<Texture2D>(graphicsDevice,
            1, 1, false, SurfaceFormat::R8G8B8A8_UNorm);

        std::array<std::uint32_t, 1> pixelData = {0xffffffff};
        texture->SetData(pixelData.data());

        renderTarget = std::make_shared<RenderTarget2D>(graphicsDevice,
            clientBounds.Width, clientBounds.Height,
            false, SurfaceFormat::R8G8B8A8_UNorm, DepthFormat::None);
    }
    {
        spriteRenderer = std::make_unique<SpriteRenderer>(graphicsDevice, *assets);
        fxaa = std::make_unique<FXAA>(graphicsDevice, *assets);
        fxaa->SetViewport(clientBounds.Width, clientBounds.Height);
        screenQuad = std::make_unique<ScreenQuad>(graphicsDevice);
        polygonBatch = std::make_unique<PolygonBatch>(graphicsContext, graphicsDevice, *assets);
    }
    {
        gameEditor = std::make_unique<SceneEditor::InGameEditor>(gameHost);
        editorBackground = std::make_unique<SceneEditor::EditorBackground>(gameHost);
    }

    {
        mainCamera = gameWorld.CreateObject();
        mainCamera.AddComponent<Transform2D>();
        mainCamera.AddComponent<Camera2D>();
    }
    {
        auto textureAtlas = TexturePacker::TextureAtlasLoader::Load(*assets, "MaidChan2/skeleton.atlas");
        auto skeletonDesc = Spine::SkeletonDescLoader::Load(*assets, "MaidChan2/skeleton.json");
        maidTexture = assets->Load<Texture2D>("MaidChan2/skeleton.png");

        LogTexturePackerInfo(textureAtlas);
        LogSkeletalInfo(skeletonDesc);

        maidSkeleton = std::make_shared<Skeleton>(Spine::CreateSkeleton(skeletonDesc.Bones));
        maidSkeletonPose = std::make_shared<SkeletonPose>(SkeletonPose::CreateBindPose(*maidSkeleton));
        auto animationClip = std::make_shared<AnimationClip>(Spine::CreateAnimationClip(skeletonDesc, "Walk"));
        maidAnimationState = std::make_shared<AnimationState>(animationClip, 1.0f, true);
        maidAnimationClipIdle = std::make_shared<AnimationClip>(Spine::CreateAnimationClip(skeletonDesc, "Idle"));

        maidSkin = Spine::CreateSkin(skeletonDesc, textureAtlas, "default");
        maidSpriteAnimationTracks = Spine::CreateSpriteAnimationTrack(skeletonDesc, textureAtlas, "Walk");

        animationSystem.Add(maidAnimationState, maidSkeleton, maidSkeletonPose);

        maidGlobalPose = SkeletonHelper::ToGlobalPose(*maidSkeleton, *maidSkeletonPose);

        // NOTE: for Skinning
        auto bindPose = SkeletonPose::CreateBindPose(*maidSkeleton);
        maidSkinnedMesh = Spine::CreateSkinnedMesh(*graphicsDevice,
            SkeletonHelper::ToGlobalPose(*maidSkeleton, bindPose),
            skeletonDesc, textureAtlas,
            Vector2(maidTexture->Width(), maidTexture->Height()), "default");
        maidSkinningEffect = std::make_unique<SkinnedEffect>(*graphicsDevice, *assets);
    }

    {
        scenePanel = std::make_shared<UI::ScenePanel>(clientBounds.Width, clientBounds.Height);
        scenePanel->cameraObject = mainCamera;
        gameEditor->AddView(scenePanel);
    }
    {
        auto stackPanel = std::make_shared<UI::StackPanel>(124, 170);
        stackPanel->Transform(Matrix3x2::CreateTranslation(Vector2{5, 10}));
        gameEditor->AddView(stackPanel);

        {
            auto navigator = std::make_shared<UI::DebugNavigator>(gameHost->Clock());
            stackPanel->AddChild(navigator);
        }
        {
            slider1 = std::make_shared<UI::Slider>(-2.0, 2.0);
            slider1->Value(1.0);
            stackPanel->AddChild(slider1);
        }
        {
            slider2 = std::make_shared<UI::Slider>(0.0, 1.0);
            slider2->Value(1.0);
            stackPanel->AddChild(slider2);
        }
        {
            toggleSwitch1 = std::make_shared<UI::ToggleSwitch>();
            toggleSwitch1->IsOn(true);
            toggleSwitch1->OnContent("Play");
            toggleSwitch1->OffContent("Stop");
            stackPanel->AddChild(toggleSwitch1);
        }
        {
            toggleSwitch2 = std::make_shared<UI::ToggleSwitch>();
            toggleSwitch2->IsOn(true);
            stackPanel->AddChild(toggleSwitch2);
        }
        {
            toggleSwitch3 = std::make_shared<UI::ToggleSwitch>();
            toggleSwitch3->IsOn(false);
            stackPanel->AddChild(toggleSwitch3);
        }
        {
            toggleSwitch4 = std::make_shared<UI::ToggleSwitch>();
            toggleSwitch4->IsOn(false);
            stackPanel->AddChild(toggleSwitch4);
        }
    }

    clientViewport = Viewport{0, 0, clientBounds.Width, clientBounds.Height};

    connections.Connect(window->ClientSizeChanged, [this](int width, int height) {
        clientViewport = Viewport{0, 0, width, height};

        renderTarget = std::make_shared<RenderTarget2D>(
            graphicsDevice, width, height,
            false, SurfaceFormat::R8G8B8A8_UNorm, DepthFormat::None);

        fxaa->SetViewport(width, height);
        spriteRenderer->SetProjectionMatrix(Matrix4x4::CreateOrthographicLH(width, height, 1.0f, 100.0f));
    });
}
Exemple #13
0
void Ovus::Scale(const Vector3d&, const TRANSFORM *tr)
{
    Transform(tr);
}
void Jade (
	     double *B, /* Output. Separating matrix. nbc*nbc */
	     double *X, /* Input.  Data set nbc x nbs */
	     int nbc,   /* Input.  Number of sensors  */
	     int nbs    /* Input.  Number of samples  */
	     )
{
  double threshold_JD = RELATIVE_JD_THRESHOLD / sqrt((double)nbs) ;
  int rots = 1 ;
  double *Transf  = (double *) calloc(nbc*nbc,         sizeof(double)) ; 
  double *CumTens = (double *) calloc(nbc*nbc*nbc*nbc, sizeof(double)) ; 
  if ( Transf == NULL || CumTens == NULL ) OutOfMemory() ;

  /* Init */
  Message0(2, "Init...\n") ;
  Identity(B, nbc); 

  MeanRemoval(X, nbc, nbs)  ; 
printf ("mean\n");

  PrintMat (X, nbc, nbs) ;
printf ("\n");

Message0(2, "Whitening...\n") ;	
  ComputeWhitener(Transf, X, nbc, nbs)  ; 
	
  printf ("Whitener:\n");
  PrintMat (Transf, nbc, nbc) ;
printf ("\n");

  Transform (X, Transf,          nbc, nbs) ;
printf ("Trans X\n");
PrintMat (X, nbc, nbs) ;
printf ("\n");

  Transform (B, Transf,          nbc, nbc) ;


  Message0(2, "Estimating the cumulant tensor...\n") ;
  EstCumTens (CumTens, X,      nbc, nbs) ;

  printf ("cum tens \n");
  PrintMat (CumTens, nbc*nbc, nbc*nbc) ;
	printf ("\n");

  Message0(2, "Joint diagonalization...\n") ;
  rots = JointDiago (CumTens, Transf,  nbc, nbc*nbc, threshold_JD) ;
  MessageI(3, "Total number of plane rotations: %6i.\n", rots) ;
  MessageF(3, "Size of the total rotation: %10.7e\n", NonIdentity(Transf,nbc) )  ;
  
  printf ("Trans mat\n");
  PrintMat (Transf, nbc, nbc) ;
  printf ("\n");

  Message0(2, "Updating...\n") ;
  Transform  (X, Transf,        nbc, nbs ) ;
  Transform  (B, Transf,        nbc, nbc ) ;

  printf ("resultant \n");
  PrintMat (X, nbc, nbs) ;
  printf ("\n");

  printf ("estimated mix \n");
  PrintMat (B, nbc, nbc) ;
  printf ("\n");

  free(Transf) ; 
  free(CumTens) ;
}
 void Painter::pushTransform(iXY translate)
 {
     transforms.push(Transform(translate));
     currentTransform += transforms.top();
 }
Exemple #16
0
HashReturn Final(hashState* ctx,
		 BitSequence* output) {

  int i, j = 0, hashbytelen = ctx->hashbitlen/8;
  u8 *s = (BitSequence*)ctx->chaining;

u64 kbyts=0,kbits;	//ADDED

  /* pad with '1'-bit and first few '0'-bits */
  if (BILB) {
    ctx->buffer[(int)ctx->buf_ptr-1] &= ((1<<BILB)-1)<<(8-BILB);
    ctx->buffer[(int)ctx->buf_ptr-1] ^= 0x1<<(7-BILB);
    BILB = 0;
  }
  else ctx->buffer[(int)ctx->buf_ptr++] = 0x80;

  /* pad with '0'-bits */
//modified :1 byte for r value & 8 bytes for length

  if (ctx->buf_ptr > ctx->blocksize-LENGTHFIELDLEN-1) { ////Modified 1 byte for r value & 8 bytes for length

    /* padding requires two blocks */
    while (ctx->buf_ptr < ctx->blocksize) {
      ctx->buffer[(int)ctx->buf_ptr++] = 0;
	kbyts++; 		//ADDED: no of zeros appended
    }

    /* digest first padding block */
    Transform(ctx, ctx->buffer, ctx->blocksize);	//Modified
    ctx->buf_ptr = 0;
  }

  while (ctx->buf_ptr < ctx->blocksize-LENGTHFIELDLEN-1) {	//Modified
    ctx->buffer[(int)ctx->buf_ptr++] = 0;
	kbyts++; 		//no of zeros appended
  }

//ADDSED bY GURPREET-- Feb14,2012

//for k zeros
  while (ctx->buf_ptr < ctx->blocksize-LENGTHFIELDLEN-1) {
    ctx->buffer[(int)ctx->buf_ptr++] = 0;
	kbyts++; 		//no of zeros appended
  }

    //ADDED BY gurpreet FOR R-BYTES
	kbits=(kbyts*8)+ctx->bits_in_last_byte;

	kbits+=8;		//7bits as 10000000 & added 1 bit as space is 7bits for rbytes
	int r_bytes;
	// for 7 bit r_bytes padding

	r_bytes=(952-kbits)%1024;
	while (r_bytes<0)
	   {r_bytes+=1024;}		// convert -vr to +ve mod value
	r_bytes/=8;			// convert it into bytes

	//for 7bit r_bytes value
	 while (ctx->buf_ptr >= ctx->blocksize-LENGTHFIELDLEN-1) {
	    ctx->buffer[ctx->buf_ptr--] = (u8)r_bytes;
	    r_bytes >>= 8;
	  } 

    //-----

  /* length padding */
  ctx->block_counter++;
  ctx->buf_ptr = ctx->blocksize;		//modified
//ADDED
   ctx->cnt_block=ctx->block_counter;
//------

/*for padding block counter*/
  while (ctx->buf_ptr > ctx->blocksize-LENGTHFIELDLEN) {	//modified
    ctx->buffer[(int)--ctx->buf_ptr] = (u8)ctx->block_counter;
    ctx->block_counter >>= 8;
  }

  /* digest final padding block */
  Transform(ctx, ctx->buffer, ctx->blocksize);		//modified
  /* perform output transformation */
  OutputTransformation(ctx);

j=0;
  /* store hash result in output */
  for (i = ctx->size-hashbytelen; i < ctx->size; i++,j++) {
    output[j] = s[i];
  }

  /* zeroise relevant variables and deallocate memory */
  if (ctx->size == SHORT) {
    memset(ctx->chaining, 0, COLS512*sizeof(u64));
    memset(ctx->buffer, 0, SIZE512);
  }
  else {
    memset(ctx->chaining, 0, COLS1024*sizeof(u64));
    memset(ctx->buffer, 0, SIZE1024);
  }
  free(ctx->chaining);
  free(ctx->buffer);

  return SUCCESS;
}
Exemple #17
0
void
SeekerAI::FindObjective()
{
    if (!shot || !target) return;

    if (target->Life() == 0) {
        if (target != orig_target)
        SetTarget(orig_target,0);
        else
        SetTarget(0,0);

        return;
    }

    Point tloc = target->Location();
    tloc = Transform(tloc);

    // seeker head limit of 45 degrees:
    if (tloc.z < 0 || tloc.z < fabs(tloc.x) || tloc.z < fabs(tloc.y)) {
        overshot = true;
        SetTarget(0,0);
        return;
    }

    // distance from self to target:
    distance = Point(target->Location() - self->Location()).length();

    // are we being spoofed?
    CheckDecoys(distance);

    Point cv = ClosingVelocity();

    // time to reach target:
    double time    = distance / cv.length();
    double predict = time;
    if (predict > 15)
    predict = 15;

    // pure pursuit:
    if (pursuit == 1 || time < 0.1) {
        obj_w = target->Location();
    }

    // lead pursuit:
    else {
        // where the target will be when we reach it:
        Point run_vec = target->Velocity();
        obj_w   = target->Location() + (run_vec * predict);
    }

    // subsystem offset:
    if (subtarget) {
        Point offset = target->Location() - subtarget->MountLocation();
        obj_w -= offset;
    }
    else if (target->Type() == SimObject::SIM_SHIP) {
        Ship* tgt_ship = (Ship*) target;

        if (tgt_ship->IsGroundUnit())
        obj_w += Point(0,150,0);
    }


    distance = Point(obj_w - self->Location()).length();
    time     = distance / cv.length();

    // where we will be when the target gets there:
    if (predict > 0.1 && predict < 15) {
        Point self_dest = self->Location() + cv * predict;
        Point err = obj_w - self_dest;

        obj_w += err;
    }

    // transform into camera coords:
    objective = Transform(obj_w);
    objective.Normalize();

    shot->SetEta((int) time);

    if (shot->Owner())
    ((Ship*) shot->Owner())->SetMissileEta(shot->Identity(), (int) time);
}
Exemple #18
0
bool CollisionModel3DImpl::rayCollision(float origin[3], 
                                        float direction[3],
                                        bool closest,
                                        float segmin, 
                                        float segmax)
{
  float mintparm=9e9f,tparm;
  Vector3D col_point;
  m_ColType=Ray;
  Vector3D O;
  Vector3D D;
  if (m_Static)
  {
    O=Transform(*(Vector3D*)origin,m_InvTransform);
    D=rotateVector(*(Vector3D*)direction,m_InvTransform);
  }
  else
  {
    Matrix3D inv=m_Transform.Inverse();
    O=Transform(*(Vector3D*)origin,inv);
    D=rotateVector(*(Vector3D*)direction,inv);
  }
  if (segmin!=0.0f) // normalize ray
  {
    O+=segmin*D;
    segmax-=segmin;
    segmin=0.0f;
  }
  if (segmax<segmin) 
  {
    D=-D;
    segmax=-segmax;
  }
  std::vector<BoxTreeNode*> checks;
  checks.push_back(&m_Root);
  while (!checks.empty())
  {
    BoxTreeNode* b=checks.back();
    checks.pop_back();
    if (b->intersect(O,D,segmax))
    {
      int sons=b->getSonsNumber();
      if (sons)
        while (sons--) checks.push_back(b->getSon(sons));
      else
      {
        int tri=b->getTrianglesNumber();
        while (tri--)
        {
          BoxedTriangle* bt=b->getTriangle(tri);
          Triangle* t=static_cast<Triangle*>(bt);
          if (t->intersect(O,D,col_point,tparm,segmax)) 
          {
            if (closest)
            {
              if (tparm<mintparm)
              {
                mintparm=tparm;
                m_ColTri1=*bt;
                m_iColTri1=getTriangleIndex(bt);
                m_ColPoint=col_point;
              }
            }
            else
            {
              m_ColTri1=*bt;
              m_iColTri1=getTriangleIndex(bt);
              m_ColPoint=col_point;
              return true;
            }
          }
        }
      }
    }
  }
  if (closest && mintparm<9e9f) return true;
  return false;
}
Exemple #19
0
void WiimoteTracker::wiimoteEventCallback(Misc::CallbackData* cbData)
	{
	/* Read the current instantaneous acceleration vector: */
	Vector newAcceleration=wiimote->getAcceleration(0);
	
	/* Update the filtered acceleration vector: */
	if(firstEvent)
		acceleration=newAcceleration;
	else
		{
		Vector da=newAcceleration-lastAcceleration;
		Scalar trust=Math::exp(-Geometry::sqr(da)*Scalar(50))*Scalar(0.2);
		acceleration+=(newAcceleration-acceleration)*trust;
		}
	lastAcceleration=newAcceleration;
	
	/* Calculate an intermediate rotation based on the filtered acceleration vector: */
	Vector previousY=wiipos.getDirection(1);
	Scalar yaw=Math::acos(previousY[1]/Math::sqrt(Math::sqr(previousY[0])+Math::sqr(previousY[1])));
	if(previousY[0]>Scalar(0))
		yaw=-yaw;
	Scalar axz=Math::sqrt(Math::sqr(acceleration[0])+Math::sqr(acceleration[2]));
	Scalar roll=Math::acos(acceleration[2]/axz);
	if(acceleration[0]>Scalar(0))
		roll=-roll;
	Scalar pitch=Math::acos(axz/Math::sqrt(Math::sqr(acceleration[1])+Math::sqr(axz)));
	if(acceleration[1]<Scalar(0))
		pitch=-pitch;
	Transform::Rotation wiirot=Transform::Rotation::rotateZ(yaw);
	wiirot*=Transform::Rotation::rotateX(pitch);
	wiirot*=Transform::Rotation::rotateY(roll);
	
	/* Update the wiimote's orientation based on the acceleration vector only: */
	wiipos=Transform(wiipos.getTranslation(),wiirot);
	
	/* Store the IR camera targets: */
	int numValidTargets=0;
	for(int i=0;i<4;++i)
		{
		pixelValids[i]=wiimote->getIRTarget(i).valid;
		if(pixelValids[i])
			{
			for(int j=0;j<2;++j)
				pixels[i][j]=Scalar(wiimote->getIRTarget(i).pos[j]);
			++numValidTargets;
			}
		}
	
	if(numValidTargets>0)
		{
		if(numValidTargets==4)
			{
			/* Project the "up" vector into camera space: */
			typedef Geometry::Vector<CameraFitter::Scalar,2> PVector;
			PVector vy(acceleration[0],acceleration[2]);
			vy.normalize();
			PVector vx=-Geometry::normal(vy);
			vx.normalize();
			
			/* Find the leftmost, rightmost, and topmost points: */
			Scalar minX,maxX,minY,maxY;
			int minXIndex,maxXIndex,minYIndex,maxYIndex;
			minX=minY=Math::Constants<Scalar>::max;
			maxX=maxY=Math::Constants<Scalar>::min;
			minXIndex=maxXIndex=minYIndex=maxYIndex=-1;
			for(int i=0;i<4;++i)
				{
				Scalar x=pixels[i]*vx;
				Scalar y=pixels[i]*vy;
				if(minX>x)
					{
					minX=x;
					minXIndex=i;
					}
				if(maxX<x)
					{
					maxX=x;
					maxXIndex=i;
					}
				if(minY>y)
					{
					minY=y;
					minYIndex=i;
					}
				if(maxY<y)
					{
					maxY=y;
					maxYIndex=i;
					}
				}
			
			/* Create the pixel-target map: */
			pixelMap[minXIndex]=0;
			pixelMap[maxYIndex]=1;
			pixelMap[maxXIndex]=2;
			for(int i=0;i<4;++i)
				if(i!=minXIndex&&i!=maxYIndex&&i!=maxXIndex)
					pixelMap[i]=3;
			}
		else
			{
			/* Project the target points into camera space using the previous camera position/orientation and match closest pairs: */
			wiiCamera.setTransform(wiipos);
			for(int pixelIndex=0;pixelIndex<4;++pixelIndex)
				if(pixelValids[pixelIndex])
					{
					Scalar minDist2=Geometry::sqrDist(pixels[pixelIndex],wiiCamera.project(0));
					int minIndex=0;
					for(int i=1;i<4;++i)
						{
						Scalar dist2=Geometry::sqrDist(pixels[pixelIndex],wiiCamera.project(i));
						if(minDist2>dist2)
							{
							minDist2=dist2;
							minIndex=i;
							}
						}
					pixelMap[pixelIndex]=minIndex;
					}
			}
		
		/* Re-project the new pixel positions: */
		wiiCamera.setTransform(homeTransform);
		for(int i=0;i<4;++i)
			wiiCamera.invalidatePixel(i);
		for(int i=0;i<4;++i)
			if(pixelValids[i])
				wiiCamera.setPixel(pixelMap[i],pixels[i]);
		wiiCamera.setTransform(homeTransform);
		wiiCameraMinimizer.minimize(wiiCamera);
		
		if(firstEvent)
			wiipos=wiiCamera.getTransform();
		else
			{
			/* Filter the reconstructed camera transformation: */
			Transform deltaWP=Geometry::invert(wiipos);
			deltaWP.leftMultiply(wiiCamera.getTransform());
			Vector t=deltaWP.getTranslation();
			t*=Scalar(0.05);
			Vector r=deltaWP.getRotation().getScaledAxis();
			r*=Scalar(0.05);
			deltaWP=Transform(t,Transform::Rotation::rotateScaledAxis(r));
			wiipos.leftMultiply(deltaWP);
			}
		}
	wiipos.renormalize();
	firstEvent=false;
	
	if(wiimote->getButtonState(Wiimote::BUTTON_HOME))
		wiipos=homeTransform;
	
	if(reportEvents)
		{
		/* Update the VR device state: */
		for(int i=0;i<13;++i)
			setButtonState(i,wiimote->getButtonState(i));
		for(int i=0;i<2;++i)
			setValuatorState(i,wiimote->getJoystickValue(i));
		Vrui::VRDeviceState::TrackerState ts;
		ts.positionOrientation=PositionOrientation(wiipos);
		ts.linearVelocity=Vrui::VRDeviceState::TrackerState::LinearVelocity::zero;
		ts.angularVelocity=Vrui::VRDeviceState::TrackerState::AngularVelocity::zero;
		setTrackerState(0,ts);
		}
	}
Exemple #20
0
bool CollisionModel3DImpl::collision(CollisionModel3D* other, 
                                     int AccuracyDepth, 
                                     int MaxProcessingTime,
                                     float* other_transform)
{
  m_ColType=Models;
  CollisionModel3DImpl* o=static_cast<CollisionModel3DImpl*>(other);
  if (!m_Final) throw Inconsistency();
  if (!o->m_Final) throw Inconsistency();
  Matrix3D t=( other_transform==NULL ? o->m_Transform : *((Matrix3D*)other_transform) );
  if (m_Static) t *= m_InvTransform;
  else          t *= m_Transform.Inverse();
  RotationState rs(t);

  if (AccuracyDepth<0) AccuracyDepth=0xFFFFFF;
  if (MaxProcessingTime==0) MaxProcessingTime=0xFFFFFF;
  
  DWORD EndTime,BeginTime = GetTickCount();
  int num=Max(m_Triangles.size(),o->m_Triangles.size());
  int Allocated=Max(64,(num>>4));
  std::vector<Check> checks(Allocated);
  
  int queue_idx=1;
  Check& c=checks[0];
  c.m_first=&m_Root;
  c.depth=0;
  c.m_second=&o->m_Root;
  while (queue_idx>0)
  {
    if (queue_idx>(Allocated/2)) // enlarge the queue.
    {
      Check c;
      checks.insert(checks.end(),Allocated,c);
      Allocated*=2;
    }
    EndTime=GetTickCount();
    if (EndTime >= (BeginTime+MaxProcessingTime)) throw TimeoutExpired();

    // @@@ add depth check
    //Check c=checks.back();
    Check& c=checks[--queue_idx];
    BoxTreeNode* first=c.m_first;
    BoxTreeNode* second=c.m_second;
    assert(first!=NULL);
    assert(second!=NULL);
    if (first->intersect(*second,rs))
    {
      int tnum1=first->getTrianglesNumber();
      int tnum2=second->getTrianglesNumber();
      if (tnum1>0 && tnum2>0)
      {
        {
          for(int i=0;i<tnum2;i++)
          {
            BoxedTriangle* bt2=second->getTriangle(i);
            Triangle tt(Transform(bt2->v1,rs.t),Transform(bt2->v2,rs.t),Transform(bt2->v3,rs.t));
            for(int j=0;j<tnum1;j++)
            {
              BoxedTriangle* bt1=first->getTriangle(j);
              if (tt.intersect(*bt1)) 
              {
                m_ColTri1=*bt1;
                m_iColTri1=getTriangleIndex(bt1);
                m_ColTri2=tt;
                m_iColTri2=o->getTriangleIndex(bt2);
                return true;
              }
            }
          }
        }
      }
      else
      if (first->getSonsNumber()==0)
      {
        BoxTreeNode* s1=second->getSon(0);
        BoxTreeNode* s2=second->getSon(1);
        assert(s1!=NULL);
        assert(s2!=NULL);
        
        Check& c1=checks[queue_idx++];
        c1.m_first=first;
        c1.m_second=s1;

        Check& c2=checks[queue_idx++];
        c2.m_first=first;
        c2.m_second=s2;
      }
      else
      if (second->getSonsNumber()==0)
      {
        BoxTreeNode* f1=first->getSon(0);
        BoxTreeNode* f2=first->getSon(1);
        assert(f1!=NULL);
        assert(f2!=NULL);
        
        Check& c1=checks[queue_idx++];
        c1.m_first=f1;
        c1.m_second=second;

        Check& c2=checks[queue_idx++];
        c2.m_first=f2;
        c2.m_second=second;
      }
      else
      {
        float v1=first->getVolume();
        float v2=second->getVolume();
        if (v1>v2)
        {
          BoxTreeNode* f1=first->getSon(0);
          BoxTreeNode* f2=first->getSon(1);
          assert(f1!=NULL);
          assert(f2!=NULL);

          Check& c1=checks[queue_idx++];
          c1.m_first=f1;
          c1.m_second=second;

          Check& c2=checks[queue_idx++];
          c2.m_first=f2;
          c2.m_second=second;
        }
        else
        {
          BoxTreeNode* s1=second->getSon(0);
          BoxTreeNode* s2=second->getSon(1);
          assert(s1!=NULL);
          assert(s2!=NULL);

          Check& c1=checks[queue_idx++];
          c1.m_first=first;
          c1.m_second=s1;

          Check& c2=checks[queue_idx++];
          c2.m_first=first;
          c2.m_second=s2;
        }
      }
    }
  }
  return false;
}
Exemple #21
0
void Plane::Transform(const float4x4 &transform)
{
    assume(transform.Row(3).Equals(float4(0,0,0,1)));
    Transform(transform.Float3x4Part());
}
Exemple #22
0
/* T1_GetStringOutline(...): Generate the outline for a string of
                             characters */
T1_OUTLINE *T1_GetStringOutline( int FontID, char *string, int len, 
				 long spaceoff, int modflag, float size,
				 T1_TMATRIX *transform)
{
  int i;
  int mode;
  /* initialize this to NULL just to be on the safe side */
  T1_PATHSEGMENT *charpath = NULL;
  struct XYspace *Current_S;
  int *kern_pairs;       /* use for accessing the kern pairs if kerning is
			    requested */
  int no_chars=0;        /* The number of characters in the string */
  static int lastno_chars=0;
  long spacewidth;       /* This is given to fontfcnb_string() */
  
  
  FONTSIZEDEPS *font_ptr;
  FONTPRIVATE  *fontarrayP;
  
  static int *pixel_h_anchor_corr=NULL;
  static int *flags=NULL;

  unsigned char *ustring;


  /* We return to this if something goes wrong deep in the rasterizer */
  if ((i=setjmp( stck_state))!=0) {
    T1_errno=T1ERR_TYPE1_ABORT;
    sprintf( err_warn_msg_buf, "t1_abort: Reason: %s",
	     t1_get_abort_message( i));
    T1_PrintLog( "T1_GetStringOutline()", err_warn_msg_buf,
	       T1LOG_ERROR);
    return( NULL);
  }

  /* force string elements into unsigned */
  ustring=(unsigned char*)string;
  
  /* First, check for a correct ID */
  i=CheckForFontID(FontID);
  if (i==-1){
    T1_errno=T1ERR_INVALID_FONTID;
    return(NULL);
  }
  /* if necessary load font into memory */
  if (i==0)
    if (T1_LoadFont(FontID))
      return(NULL);

  /* If no AFM info is present, we return an error */
  if (pFontBase->pFontArray[FontID].pAFMData==NULL) {
    T1_errno=T1ERR_NO_AFM_DATA;
    return(NULL);
  }

  /* Check for valid size */
  if (size<=0.0){
    T1_errno=T1ERR_INVALID_PARAMETER;
    return(NULL);
  }

  fontarrayP=&(pFontBase->pFontArray[FontID]);
  
  /* font is now loaded into memory =>
     Check for size: */
  if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
    font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS);
    if (font_ptr==NULL){
      T1_errno=T1ERR_ALLOC_MEM;
      return(NULL);
    }
  }
  
  /* Now comes string specific stuff: Get length of string and create an
     array of integers where to store the bitmap positioning dimens: */
  if (len<0){  /* invalid length */
    T1_errno=T1ERR_INVALID_PARAMETER;
    return(NULL);
  }
  
  if (len==0) /* should be computed assuming "normal" 0-terminated string */
    no_chars=strlen(string);
  else        /* use value given on command line */
    no_chars=len;

  /* If necessary, allocate memory */
  if (no_chars>lastno_chars){
    if (pixel_h_anchor_corr!=NULL){
      free(pixel_h_anchor_corr);
    }
    if (flags!=NULL){
      free(flags);
    }
    
    pixel_h_anchor_corr=(int *)calloc(no_chars, sizeof(int));
    flags=(int *)calloc(no_chars, sizeof(int));
    lastno_chars=no_chars;
  }
  else{
    /* Reset flags  and position array */
    for (i=0; i<no_chars; i++){
      flags[i]=0;
      pixel_h_anchor_corr[i]=0;
    }
  }
  
  /* Setup an appropriate charspace matrix. Note that the rasterizer
     assumes vertical values with inverted sign! Transformation should
     create a copy of the local charspace matrix which then still has
     to be made permanent. */
  if (transform!=NULL){
    Current_S=(struct XYspace *) 
      Permanent(Scale(Transform (font_ptr->pCharSpaceLocal,
				 transform->cxx, - transform->cxy,
				 transform->cyx, - transform->cyy),
		      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
  }
  else{
    Current_S=(struct XYspace *)
      Permanent(Scale(Transform(font_ptr->pCharSpaceLocal,
				1.0, 0.0, 0.0, -1.0),
		      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
  }
  
  /* Compute the correct spacewidth value (in charspace units). The
     value supplied by the user is interpreted as an offset in
     char space units:
     */
  spacewidth=T1_GetCharWidth(FontID,fontarrayP->space_position)+spaceoff;
  
  mode=0;
  kern_pairs=(int *)calloc(no_chars, sizeof(int));
  if ((modflag & T1_KERNING))
    for (i=0; i<no_chars -1; i++)
      kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]);
  charpath=(T1_PATHSEGMENT *) fontfcnB_string( FontID, modflag, Current_S,
					       fontarrayP->pFontEnc,
					       (unsigned char *)string,
					       no_chars, &mode,
					       fontarrayP->pType1Data,
					       kern_pairs, spacewidth,
					       DO_NOT_RASTER);
  KillSpace (Current_S);
  
  /* In all cases, free memory for kerning pairs */
  free(kern_pairs);
  
  /* fill the string_glyph-structure */
  if (mode != 0) {
    sprintf( err_warn_msg_buf, "fontfcnB_string() set mode=%d", mode);
    T1_PrintLog( "T1_GetStringOutline()", err_warn_msg_buf, T1LOG_WARNING);
    T1_errno=mode;
    /* make sure to get rid of path if it's there */
    if (charpath){
      KillRegion (charpath);
    }
    return(NULL);
  }
  if (charpath == NULL){
    T1_PrintLog( "T1_GetStringOutline()", "path=NULL returned by fontfcnB_string()", T1LOG_WARNING);
    T1_errno=mode;
    return(NULL);
  }
  
  return( (T1_OUTLINE *)charpath);
}
Exemple #23
0
Transform Transform::operator*(const Transform &t2) const {
    Matrix4x4 m1 = Matrix4x4::Mul(m, t2.m);
    Matrix4x4 m2 = Matrix4x4::Mul(t2.mInv, mInv);
    return Transform(m1, m2);
}
Exemple #24
0
/* T1_GetMoveOutline(...): Generate the "outline" for a movement
                           */
T1_OUTLINE *T1_GetMoveOutline( int FontID, int deltax, int deltay, int modflag,
			       float size, T1_TMATRIX *transform)
{
  int i;
  FONTSIZEDEPS *font_ptr;
  struct segment *path, *tmppath;
  struct XYspace *Current_S;
  psfont *FontP;
  float length;
  

  /* We return to this if something goes wrong deep in the rasterizer */
  if ((i=setjmp( stck_state))!=0) {
    T1_errno=T1ERR_TYPE1_ABORT;
    sprintf( err_warn_msg_buf, "t1_abort: Reason: %s",
	     t1_get_abort_message( i));
    T1_PrintLog( "T1_GetMoveOutline()", err_warn_msg_buf,
	       T1LOG_ERROR);
    return( NULL);
  }


  /* First, check for a correct ID */
  i=CheckForFontID(FontID);
  if (i==-1){
    T1_errno=T1ERR_INVALID_FONTID;
    return(NULL);
  }
  /* if necessary load font into memory */
  if (i==0)
    if (T1_LoadFont(FontID))
      return(NULL);

  /* Check for valid size */
  if (size<=0.0){
    T1_errno=T1ERR_INVALID_PARAMETER;
    return(NULL);
  }

  FontP=pFontBase->pFontArray[i].pType1Data;
  
  /* font is now loaded into memory =>
     Check for size: */
  if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
    font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS);
    if (font_ptr==NULL){
      T1_errno=T1ERR_ALLOC_MEM;
      return(NULL);
    }
  }

  /* Setup an appropriate charspace matrix. Note that the rasterizer
     assumes vertical values with inverted sign! Transformation should
     create a copy of the local charspace matrix which then still has
     to be made permanent. */
  if (transform!=NULL){
    Current_S=(struct XYspace *) 
      Permanent(Scale(Transform (font_ptr->pCharSpaceLocal,
				 transform->cxx, - transform->cxy,
				 transform->cyx, - transform->cyy),
		      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
  }
  else{
    Current_S=(struct XYspace *)
      Permanent(Scale(Transform(font_ptr->pCharSpaceLocal,
				1.0, 0.0, 0.0, -1.0),
		      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
  }
  
  
  path=(struct segment *)ILoc( Current_S, deltax, deltay); 

  /* Take care for underlining and such */
  length=(float) deltax;
  if (modflag & T1_UNDERLINE){
    tmppath=(struct segment *)Type1Line(FontP,Current_S,
					pFontBase->pFontArray[FontID].UndrLnPos,
					pFontBase->pFontArray[FontID].UndrLnThick,
					length);
    path=(struct segment *)Join(path,tmppath);
  }
  if (modflag & T1_OVERLINE){
    tmppath=(struct segment *)Type1Line(FontP,Current_S,
					pFontBase->pFontArray[FontID].OvrLnPos,
					pFontBase->pFontArray[FontID].OvrLnThick,
					length);
    path=(struct segment *)Join(path,tmppath);
  }
  if (modflag & T1_OVERSTRIKE){
    tmppath=(struct segment *)Type1Line(FontP,Current_S,
					pFontBase->pFontArray[FontID].OvrStrkPos,
					pFontBase->pFontArray[FontID].OvrStrkThick,
					length);
    path=(struct segment *)Join(path,tmppath);
  }
      
  KillSpace( Current_S);
  
  return( (T1_OUTLINE *)path);
  
}
Exemple #25
0
void SkeletonModel::renderJointConstraints(gpu::Batch& batch, int jointIndex) {
    if (jointIndex == -1 || jointIndex >= _rig->getJointStateCount()) {
        return;
    }
    const FBXGeometry& geometry = _geometry->getFBXGeometry();
    const float BASE_DIRECTION_SIZE = 0.3f;
    float directionSize = BASE_DIRECTION_SIZE * extractUniformScale(_scale);
    // FIXME: THe line width of 3.0f is not supported anymore, we ll need a workaround

    do {
        const FBXJoint& joint = geometry.joints.at(jointIndex);
        const JointState& jointState = _rig->getJointState(jointIndex);
        glm::vec3 position = _rotation * jointState.getPosition() + _translation;
        glm::quat parentRotation = (joint.parentIndex == -1) ?
            _rotation :
            _rotation * _rig->getJointState(joint.parentIndex).getRotation();
        float fanScale = directionSize * 0.75f;
        
        Transform transform = Transform();
        transform.setTranslation(position);
        transform.setRotation(parentRotation);
        transform.setScale(fanScale);
        batch.setModelTransform(transform);
        
        const int AXIS_COUNT = 3;

        auto geometryCache = DependencyManager::get<GeometryCache>();

        for (int i = 0; i < AXIS_COUNT; i++) {
            if (joint.rotationMin[i] <= -PI + EPSILON && joint.rotationMax[i] >= PI - EPSILON) {
                continue; // unconstrained
            }
            glm::vec3 axis;
            axis[i] = 1.0f;
            
            glm::vec3 otherAxis;
            if (i == 0) {
                otherAxis.y = 1.0f;
            } else {
                otherAxis.x = 1.0f;
            }
            glm::vec4 color(otherAxis.r, otherAxis.g, otherAxis.b, 0.75f);

            QVector<glm::vec3> points;
            points << glm::vec3(0.0f, 0.0f, 0.0f);
            const int FAN_SEGMENTS = 16;
            for (int j = 0; j < FAN_SEGMENTS; j++) {
                glm::vec3 rotated = glm::angleAxis(glm::mix(joint.rotationMin[i], joint.rotationMax[i],
                    (float)j / (FAN_SEGMENTS - 1)), axis) * otherAxis;
                points << rotated;
            }
            // TODO: this is really inefficient constantly recreating these vertices buffers. It would be
            // better if the skeleton model cached these buffers for each of the joints they are rendering
            geometryCache->updateVertices(_triangleFanID, points, color);
            geometryCache->renderVertices(batch, gpu::TRIANGLE_FAN, _triangleFanID);
            
        }
        
        renderOrientationDirections(batch, jointIndex, position, _rotation * jointState.getRotation(), directionSize);
        jointIndex = joint.parentIndex;
        
    } while (jointIndex != -1 && geometry.joints.at(jointIndex).isFree);
}
Exemple #26
0
/* T1_SetChar(...): Generate the bitmap for a character */
T1_OUTLINE *T1_GetCharOutline( int FontID, char charcode, float size,
			       T1_TMATRIX *transform)
{
  int i;
  int mode;
  T1_PATHSEGMENT *charpath;
  struct XYspace *Current_S;
  unsigned char ucharcode;
  
  
  FONTSIZEDEPS *font_ptr;
  FONTPRIVATE  *fontarrayP;
  
  /* We don't implement underlining for characters, but the rasterer
     implements it. Thus, we use a modflag of constant 0 */
  int modflag=0;

  
  /* We return to this if something goes wrong deep in the rasterizer */
  if ((i=setjmp( stck_state))!=0) {
    T1_errno=T1ERR_TYPE1_ABORT;
    sprintf( err_warn_msg_buf, "t1_abort: Reason: %s",
	     t1_get_abort_message( i));
    T1_PrintLog( "T1_GetCharOutline()", err_warn_msg_buf,
	       T1LOG_ERROR);
    return( NULL);
  }

  ucharcode=(unsigned char)charcode;

  
  /* First, check for a correct ID */
  i=CheckForFontID(FontID);
  if (i==-1){
    T1_errno=T1ERR_INVALID_FONTID;
    return(NULL);
  }
  /* if necessary load font into memory */
  if (i==0)
    if (T1_LoadFont(FontID))
      return(NULL);

  /* Check for valid size */
  if (size<=0.0){
    T1_errno=T1ERR_INVALID_PARAMETER;
    return(NULL);
  }

  fontarrayP=&(pFontBase->pFontArray[FontID]);
  
  /* font is now loaded into memory =>
     Check for size: */
  if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){
    font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS);
    if (font_ptr==NULL){
      T1_errno=T1ERR_ALLOC_MEM;
      return(NULL);
    }
  }
  
  /* Setup an appropriate charspace matrix. Note that the rasterizer
     assumes vertical values with inverted sign! Transformation should
     create a copy of the local charspace matrix which then still has
     to be made permanent. */
  if (transform!=NULL) {
    Current_S=(struct XYspace *) 
      Permanent(Scale(Transform (font_ptr->pCharSpaceLocal,
				 transform->cxx, - transform->cxy,
				 transform->cyx, - transform->cyy),
		      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
  }
  else{
    Current_S=(struct XYspace *)
      Permanent(Scale(Transform(font_ptr->pCharSpaceLocal,
				1.0, 0.0, 0.0, -1.0),
		      DeviceSpecifics.scale_x, DeviceSpecifics.scale_y));
  }

  
  /* fnt_ptr now points to the correct FontSizeDeps-struct =>
     lets now raster the character */
  mode=0;
  charpath=(T1_PATHSEGMENT *)fontfcnB( FontID, modflag, Current_S,
				       fontarrayP->pFontEnc,
				       ucharcode, &mode,
				       fontarrayP->pType1Data,
				       DO_NOT_RASTER);
  KillSpace (Current_S);

  return((T1_OUTLINE *)charpath);
}
Exemple #27
0
RES ResourceFormatLoaderShader::load(const String &p_path,const String& p_original_path) {

	String fragment_code;
	String vertex_code;
	String light_code;

	int mode=-1;

	Error err;
	FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);


	ERR_EXPLAIN("Unable to open shader file: "+p_path);
	ERR_FAIL_COND_V(err,RES());
	String base_path = p_path.get_base_dir();


	Ref<Shader> shader;//( memnew( Shader ) );

	int line=0;

	while(!f->eof_reached()) {

		String l = f->get_line();
		line++;

		if (mode<=0) {
			l = l.strip_edges();
			int comment = l.find(";");
			if (comment!=-1)
				l=l.substr(0,comment);
		}

		if (mode<1)
			vertex_code+="\n";
		if (mode<2)
			fragment_code+="\n";

		if (mode < 1 && l=="")
			continue;

		if (l.begins_with("[")) {
			l=l.strip_edges();
			if (l=="[params]") {
				if (mode>=0) {
					memdelete(f);
					ERR_EXPLAIN(p_path+":"+itos(line)+": Misplaced [params] section.");
					ERR_FAIL_V(RES());
				}
				mode=0;
			}  else if (l=="[vertex]") {
				if (mode>=1) {
					memdelete(f);
					ERR_EXPLAIN(p_path+":"+itos(line)+": Misplaced [vertex] section.");
					ERR_FAIL_V(RES());
				}
				mode=1;
			}  else if (l=="[fragment]") {
				if (mode>=2) {
					memdelete(f);
					ERR_EXPLAIN(p_path+":"+itos(line)+": Misplaced [fragment] section.");
					ERR_FAIL_V(RES());
				}
				mode=1;
			} else {
				memdelete(f);
				ERR_EXPLAIN(p_path+":"+itos(line)+": Unknown section type: '"+l+"'.");
				ERR_FAIL_V(RES());
			}
			continue;
		}

		if (mode==0) {

			int eqpos = l.find("=");
			if (eqpos==-1) {
				memdelete(f);
				ERR_EXPLAIN(p_path+":"+itos(line)+": Expected '='.");
				ERR_FAIL_V(RES());
			}


			String right=l.substr(eqpos+1,l.length()).strip_edges();
			if (right=="") {
				memdelete(f);
				ERR_EXPLAIN(p_path+":"+itos(line)+": Expected value after '='.");
				ERR_FAIL_V(RES());
			}

			Variant value;

			if (right=="true") {
				value = true;
			} else if (right=="false") {
				value = false;
			} else if (right.is_valid_float()) {
				//is number
				value = right.to_double();
			} else if (right.is_valid_html_color()) {
				//is html color
				value = Color::html(right);
			} else {
				//attempt to parse a constructor
				int popenpos = right.find("(");

				if (popenpos==-1) {
					memdelete(f);
					ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor syntax: "+right);
					ERR_FAIL_V(RES());
				}

				int pclosepos = right.find_last(")");

				if (pclosepos==-1) {
					ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor parameter syntax: "+right);
					ERR_FAIL_V(RES());

				}

				String type = right.substr(0,popenpos);
				String param = right.substr(popenpos+1,pclosepos-popenpos-1).strip_edges();

				print_line("type: "+type+" param: "+param);

				if (type=="tex") {

					if (param=="") {

						value=RID();
					} else {

						String path;

						if (param.is_abs_path())
							path=param;
						else
							path=base_path+"/"+param;

						Ref<Texture> texture = ResourceLoader::load(path);
						if (!texture.is_valid()) {
							memdelete(f);
							ERR_EXPLAIN(p_path+":"+itos(line)+": Couldn't find icon at path: "+path);
							ERR_FAIL_V(RES());
						}

						value=texture;
					}

				} else if (type=="vec3") {

					if (param=="") {
						value=Vector3();
					} else {
						Vector<String> params = param.split(",");
						if (params.size()!=3) {
							memdelete(f);
							ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid param count for vec3(): '"+right+"'.");
							ERR_FAIL_V(RES());

						}

						Vector3 v;
						for(int i=0;i<3;i++)
							v[i]=params[i].to_double();
						value=v;
					}


				} else if (type=="xform") {

					if (param=="") {
						value=Transform();
					} else {

						Vector<String> params = param.split(",");
						if (params.size()!=12) {
							memdelete(f);
							ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid param count for xform(): '"+right+"'.");
							ERR_FAIL_V(RES());

						}

						Transform t;
						for(int i=0;i<9;i++)
							t.basis[i%3][i/3]=params[i].to_double();
						for(int i=0;i<3;i++)
							t.origin[i]=params[i-9].to_double();

						value=t;
					}

				} else {
					memdelete(f);
					ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor type: '"+type+"'.");
					ERR_FAIL_V(RES());

				}

			}

			String left= l.substr(0,eqpos);

//			shader->set_param(left,value);
		} else if (mode==1) {

			vertex_code+=l;

		} else if (mode==2) {

			fragment_code+=l;
		}
	}

	shader->set_code(vertex_code,fragment_code,light_code);

	f->close();
	memdelete(f);

	return shader;
}
Patch::Patch(RenderShape& markerTemplate, RenderShape& slopeLineTemplate)
{
	_transform = Transform();
	_transform.position = glm::vec3();
	_transform.rotation = glm::quat();
	_transform.scale = glm::vec3(1.0f, 1.0f, 1.0f);

	_transform.angularVelocity = glm::quat();
	_transform.linearVelocity = glm::vec3();

	_transform.rotationOrigin = glm::vec3();
	_transform.scaleOrigin = glm::vec3();

	GLfloat data = 0.0f;
	GLint elements = 0;

	glGenVertexArrays(1, &_vao);
	glBindVertexArray(_vao);

	glGenBuffers(1, &_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, _vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat), &data, GL_DYNAMIC_DRAW);

	glGenBuffers(1, &_ebo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint), &elements, GL_DYNAMIC_DRAW);

	// Bind buffer data to shader values
	GLint posAttrib = glGetAttribLocation(slopeLineTemplate.shader().shaderPointer, "position");
	glEnableVertexAttribArray(posAttrib);
	glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);

	GLint uTransform = glGetUniformLocation(slopeLineTemplate.shader().shaderPointer, "transform");
	GLint uColor = glGetUniformLocation(slopeLineTemplate.shader().shaderPointer, "color");

	_curve = new RenderShape(_vao, NUM_ELEMENTS, GL_TRIANGLES, slopeLineTemplate.shader(), glm::vec4(0.6f, 0.6f, 0.6f, 1.0f));

	_curve->transform().parent = &_transform;

	RenderManager::AddShape(_curve);
	GeneratePlane();

	for (int i = 0; i < 16; ++i)
	{
		_controlPointMarkers[i] = new RenderShape(markerTemplate);
		_controlPointMarkers[i]->transform().scale = glm::vec3(0.01f, 0.01f, 0.01f);
		_controlPointMarkers[i]->transform().position = _controlPoints[i];

		_controlPointMarkers[i]->transform().parent = &_curve->transform();

		RenderManager::AddShape(_controlPointMarkers[i]);
	}

	for (int i = 0; i < 8; ++i)
	{
		_slopeLines[i] = new RenderShape(slopeLineTemplate);

		_slopeLines[i]->transform().parent = &_curve->transform();

		RenderManager::AddShape(_slopeLines[i]);
	}

	_controlPointsActive = true;
}
bool Unit::InsideCollideTree( Unit *smaller,
                              QVector &bigpos,
                              Vector &bigNormal,
                              QVector &smallpos,
                              Vector &smallNormal,
                              bool bigasteroid,
                              bool smallasteroid )
{
    if (smaller->colTrees == NULL || this->colTrees == NULL)
        return false;
    if (hull < 0) return false;
    if (smaller->colTrees->usingColTree() == false || this->colTrees->usingColTree() == false)
        return false;
    csOPCODECollider::ResetCollisionPairs();
    Unit *bigger = this;

    csReversibleTransform bigtransform( bigger->cumulative_transformation_matrix );
    csReversibleTransform smalltransform( smaller->cumulative_transformation_matrix );
    smalltransform.SetO2TTranslation( csVector3( smaller->cumulative_transformation_matrix.p
                                                 -bigger->cumulative_transformation_matrix.p ) );
    bigtransform.SetO2TTranslation( csVector3( 0, 0, 0 ) );
    //we're only gonna lerp the positions for speed here... gahh!
    
    // Check for shield collisions here prior to checking for mesh on mesh or ray collisions below. 
    csOPCODECollider *tmpCol = smaller->colTrees->colTree( smaller, bigger->GetWarpVelocity() );
    if ( tmpCol
        && ( tmpCol->Collide( *bigger->colTrees->colTree( bigger,
                                                         smaller->GetWarpVelocity() ), &smalltransform, &bigtransform ) ) ) {
        csCollisionPair *mycollide = csOPCODECollider::GetCollisions();
        unsigned int     numHits   = csOPCODECollider::GetCollisionPairCount();
        if (numHits) {
            smallpos.Set( (mycollide[0].a1.x+mycollide[0].b1.x+mycollide[0].c1.x)/3.0f,
                         (mycollide[0].a1.y+mycollide[0].b1.y+mycollide[0].c1.y)/3.0f,
                         (mycollide[0].a1.z+mycollide[0].b1.z+mycollide[0].c1.z)/3.0f );
            smallpos = Transform( smaller->cumulative_transformation_matrix, smallpos );
            bigpos.Set( (mycollide[0].a2.x+mycollide[0].b2.x+mycollide[0].c2.x)/3.0f,
                       (mycollide[0].a2.y+mycollide[0].b2.y+mycollide[0].c2.y)/3.0f,
                       (mycollide[0].a2.z+mycollide[0].b2.z+mycollide[0].c2.z)/3.0f );
            bigpos = Transform( bigger->cumulative_transformation_matrix, bigpos );
            csVector3 sn, bn;
            sn.Cross( mycollide[0].b1-mycollide[0].a1, mycollide[0].c1-mycollide[0].a1 );
            bn.Cross( mycollide[0].b2-mycollide[0].a2, mycollide[0].c2-mycollide[0].a2 );
            sn.Normalize();
            bn.Normalize();
            smallNormal.Set( sn.x, sn.y, sn.z );
            bigNormal.Set( bn.x, bn.y, bn.z );
            smallNormal = TransformNormal( smaller->cumulative_transformation_matrix, smallNormal );
            bigNormal   = TransformNormal( bigger->cumulative_transformation_matrix, bigNormal );
            return true;
        }
    }
    un_iter i;
    static float rsizelim = XMLSupport::parse_float( vs_config->getVariable( "physics", "smallest_subunit_to_collide", ".2" ) );
    clsptr  bigtype = bigasteroid ? ASTEROIDPTR : bigger->isUnit();
    clsptr  smalltype     = smallasteroid ? ASTEROIDPTR : smaller->isUnit();
    if ( bigger->SubUnits.empty() == false
        && (bigger->graphicOptions.RecurseIntoSubUnitsOnCollision == true || bigtype == ASTEROIDPTR) ) {
        i = bigger->getSubUnits();
        float rad = smaller->rSize();
        for (Unit *un; (un = *i); ++i) {
            float subrad = un->rSize();
            if ( (bigtype != ASTEROIDPTR) && (subrad/bigger->rSize() < rsizelim) ) {
                break;
            }
            if ( ( un->Position()-smaller->Position() ).Magnitude() <= subrad+rad ) {
                if ( ( un->InsideCollideTree( smaller, bigpos, bigNormal, smallpos, smallNormal, bigtype == ASTEROIDPTR,
                                              smalltype == ASTEROIDPTR ) ) )
                    return true;
            }
        }
    }
    if ( smaller->SubUnits.empty() == false
        && (smaller->graphicOptions.RecurseIntoSubUnitsOnCollision == true || smalltype == ASTEROIDPTR) ) {
        i = smaller->getSubUnits();
        float rad = bigger->rSize();
        for (Unit *un; (un = *i); ++i) {
            float subrad = un->rSize();
            if ( (smalltype != ASTEROIDPTR) && (subrad/smaller->rSize() < rsizelim) )
                break;
            if ( ( un->Position()-bigger->Position() ).Magnitude() <= subrad+rad ) {
                if ( ( bigger->InsideCollideTree( un, bigpos, bigNormal, smallpos, smallNormal, bigtype == ASTEROIDPTR,
                                                  smalltype == ASTEROIDPTR ) ) )
                    return true;
            }
        }
    }
    //FIXME
    //doesn't check all i*j options of subunits vs subunits
    return false;
}
// Draws the FBO texture for Oculus rift.
void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int eye) {
    if (_alpha == 0.0f) {
        return;
    }

    GLuint texture = qApp->getApplicationOverlay().getOverlayTexture();
    if (!texture) {
        return;
    }

    updateTooltips();

    vec2 canvasSize = qApp->getCanvasSize();
    _textureAspectRatio = aspect(canvasSize);

    renderArgs->_context->syncCache();
    auto geometryCache = DependencyManager::get<GeometryCache>();

    gpu::Batch batch;
    geometryCache->useSimpleDrawPipeline(batch);
    batch._glDisable(GL_DEPTH_TEST);
    batch._glDisable(GL_CULL_FACE);
    batch._glBindTexture(GL_TEXTURE_2D, texture);
    batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    batch.setViewTransform(Transform());
    batch.setProjectionTransform(qApp->getEyeProjection(eye));

    mat4 eyePose = qApp->getEyePose(eye);
    glm::mat4 overlayXfm = glm::inverse(eyePose);

#ifdef DEBUG_OVERLAY
    {
        batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2)));
        geometryCache->renderUnitQuad(batch, glm::vec4(1));
    }
#else
    {
        batch.setModelTransform(overlayXfm);
        drawSphereSection(batch);
    }
#endif

    // Doesn't actually render
    renderPointers(batch);
    vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);

    bindCursorTexture(batch);

    MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
    //Controller Pointers
    for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
        PalmData& palm = myAvatar->getHand()->getPalms()[i];
        if (palm.isActive()) {
            glm::vec2 polar = getPolarCoordinates(palm);
            // Convert to quaternion
            mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
            mat4 reticleXfm = overlayXfm * pointerXfm;
            reticleXfm = glm::scale(reticleXfm, reticleScale);
            batch.setModelTransform(reticleXfm);
            // Render reticle at location
            geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
        }
    }

    //Mouse Pointer
    if (_reticleActive[MOUSE]) {
        glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(),
            _reticlePosition[MOUSE].y()));
        mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
        mat4 reticleXfm = overlayXfm * pointerXfm;
        reticleXfm = glm::scale(reticleXfm, reticleScale);
        batch.setModelTransform(reticleXfm);
        geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
    }
    
    renderArgs->_context->render(batch);
}