예제 #1
0
파일: grid_map.cpp 프로젝트: arcanis/godot
Array GridMap::get_meshes() {

	if (theme.is_null())
		return Array();

	Vector3 ofs = _get_offset();
	Array meshes;

	for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) {

		int id = E->get().item;
		if (!theme->has_item(id))
			continue;
		Ref<Mesh> mesh = theme->get_item_mesh(id);
		if (mesh.is_null())
			continue;

		IndexKey ik = E->key();

		Vector3 cellpos = Vector3(ik.x, ik.y, ik.z);

		Transform xform;

		xform.basis.set_orthogonal_index(E->get().rot);

		xform.set_origin(cellpos * cell_size + ofs);
		xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale));

		meshes.push_back(xform);
		meshes.push_back(mesh);
	}

	return meshes;
}
예제 #2
0
파일: grid_map.cpp 프로젝트: arcanis/godot
Vector3 GridMap::map_to_world(int p_x, int p_y, int p_z) const {
	Vector3 offset = _get_offset();
	Vector3 world_pos(
			p_x * cell_size.x + offset.x,
			p_y * cell_size.y + offset.y,
			p_z * cell_size.z + offset.z);
	return world_pos;
}
예제 #3
0
파일: evtimer.c 프로젝트: A-Paul/RIOT
static void _update_head_offset(evtimer_t *evtimer)
{
    if (evtimer->events) {
        evtimer_event_t *event = evtimer->events;
        event->offset = _get_offset(&evtimer->timer);
        DEBUG("evtimer: _update_head_offset(): new head offset %" PRIu32 "\n", event->offset);
    }
}
예제 #4
0
파일: grid_map.cpp 프로젝트: arcanis/godot
bool GridMap::_octant_update(const OctantKey &p_key) {
	ERR_FAIL_COND_V(!octant_map.has(p_key), false);
	Octant &g = *octant_map[p_key];
	if (!g.dirty)
		return false;

	//erase body shapes
	PhysicsServer::get_singleton()->body_clear_shapes(g.static_body);

	//erase body shapes debug
	if (g.collision_debug.is_valid()) {

		VS::get_singleton()->mesh_clear(g.collision_debug);
	}

	//erase navigation
	if (navigation) {
		for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) {
			navigation->navmesh_remove(E->get().id);
		}
		g.navmesh_ids.clear();
	}

	//erase multimeshes

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

		VS::get_singleton()->free(g.multimesh_instances[i].instance);
		VS::get_singleton()->free(g.multimesh_instances[i].multimesh);
	}
	g.multimesh_instances.clear();

	if (g.cells.size() == 0) {
		//octant no longer needed
		_octant_clean_up(p_key);
		return true;
	}

	PoolVector<Vector3> col_debug;

	/*
	 * foreach item in this octant,
	 * set item's multimesh's instance count to number of cells which have this item
	 * and set said multimesh bounding box to one containing all cells which have this item
	 */

	Map<int, List<Pair<Transform, IndexKey> > > multimesh_items;

	for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) {

		ERR_CONTINUE(!cell_map.has(E->get()));
		const Cell &c = cell_map[E->get()];

		if (!theme.is_valid() || !theme->has_item(c.item))
			continue;

		//print_line("OCTANT, CELLS: "+itos(ii.cells.size()));

		Vector3 cellpos = Vector3(E->get().x, E->get().y, E->get().z);
		Vector3 ofs = _get_offset();

		Transform xform;

		if (clip && ((clip_above && cellpos[clip_axis] > clip_floor) || (!clip_above && cellpos[clip_axis] < clip_floor))) {

		} else {
		}

		xform.basis.set_orthogonal_index(c.rot);
		xform.set_origin(cellpos * cell_size + ofs);
		xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale));

		if (theme->get_item_mesh(c.item).is_valid()) {
			if (!multimesh_items.has(c.item)) {
				multimesh_items[c.item] = List<Pair<Transform, IndexKey> >();
			}

			Pair<Transform, IndexKey> p;
			p.first = xform;
			p.second = E->get();
			multimesh_items[c.item].push_back(p);
		}

		Vector<MeshLibrary::ShapeData> shapes = theme->get_item_shapes(c.item);
		// add the item's shape at given xform to octant's static_body
		for (int i = 0; i < shapes.size(); i++) {
			// add the item's shape
			if (!shapes[i].shape.is_valid())
				continue;
			PhysicsServer::get_singleton()->body_add_shape(g.static_body, shapes[i].shape->get_rid(), xform * shapes[i].local_transform);
			if (g.collision_debug.is_valid()) {
				shapes[i].shape->add_vertices_to_array(col_debug, xform * shapes[i].local_transform);
			}

			//print_line("PHIS x: "+xform);
		}

		// add the item's navmesh at given xform to GridMap's Navigation ancestor
		Ref<NavigationMesh> navmesh = theme->get_item_navmesh(c.item);
		if (navmesh.is_valid()) {
			Octant::NavMesh nm;
			nm.xform = xform;

			if (navigation) {
				nm.id = navigation->navmesh_create(navmesh, xform, this);
			} else {
				nm.id = -1;
			}
			g.navmesh_ids[E->get()] = nm;
		}
	}

	//update multimeshes
	for (Map<int, List<Pair<Transform, IndexKey> > >::Element *E = multimesh_items.front(); E; E = E->next()) {
		Octant::MultimeshInstance mmi;

		RID mm = VS::get_singleton()->multimesh_create();
		VS::get_singleton()->multimesh_allocate(mm, E->get().size(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_NONE);
		VS::get_singleton()->multimesh_set_mesh(mm, theme->get_item_mesh(E->key())->get_rid());

		int idx = 0;
		for (List<Pair<Transform, IndexKey> >::Element *F = E->get().front(); F; F = F->next()) {
			VS::get_singleton()->multimesh_instance_set_transform(mm, idx, F->get().first);
#ifdef TOOLS_ENABLED

			Octant::MultimeshInstance::Item it;
			it.index = idx;
			it.transform = F->get().first;
			it.key = F->get().second;
			mmi.items.push_back(it);
#endif

			idx++;
		}

		RID instance = VS::get_singleton()->instance_create();
		VS::get_singleton()->instance_set_base(instance, mm);

		if (is_inside_tree()) {
			VS::get_singleton()->instance_set_scenario(instance, get_world()->get_scenario());
			VS::get_singleton()->instance_set_transform(instance, get_global_transform());
		}

		mmi.multimesh = mm;
		mmi.instance = instance;

		g.multimesh_instances.push_back(mmi);
	}

	if (col_debug.size()) {

		Array arr;
		arr.resize(VS::ARRAY_MAX);
		arr[VS::ARRAY_VERTEX] = col_debug;

		VS::get_singleton()->mesh_add_surface_from_arrays(g.collision_debug, VS::PRIMITIVE_LINES, arr);
		SceneTree *st = SceneTree::get_singleton();
		if (st) {
			VS::get_singleton()->mesh_surface_set_material(g.collision_debug, 0, st->get_debug_collision_material()->get_rid());
		}
	}

	g.dirty = false;

	return false;
}