//---------------------------------------------------------------------------- void NodeBillboard::UpdateWorldData(Double appTime, Bool updateControllers) { // Compute billboard's world transforms based on its parent's world // transform and its local transforms. Notice that you should not call // Node::UpdateWorldData since that function updates its children. The // children of a NodeBillboard cannot be updated until the billboard is // aligned with the camera. Spatial::UpdateWorldData(appTime, updateControllers); if (mspCamera) { // Inverse-transform the camera to the model space of the billboard. Vector3F camLocation = World.ApplyInverse(mspCamera->GetLocation()); // To align the billboard, the projection of the camera to the // xz-plane of the billboard's model space determines the angle of // rotation about the billboard's model y-axis. If the projected // camera is on the model axis (x = 0 and z = 0), ATan2 returns zero // (rather than NaN), so there is no need to trap this degenerate // case and handle it separately. Float angle = MathF::ATan2(camLocation.X(), camLocation.Z()); Matrix34F orientation(Vector3F::UNIT_Y, angle); World.SetRotate(World.GetMatrix() * orientation); } // update the children now that the billboard orientation is known for (UInt i = 0; i < mChildren.GetQuantity(); i++) { Spatial* pChild = mChildren[i]; if (pChild) { pChild->UpdateGS(appTime, false, updateControllers); } } }
//---------------------------------------------------------------------------- void Node::GetVisibleSet(Culler& rCuller, Bool noCull) { for (UInt i = 0; i < mEffects.GetQuantity(); i++) { // This is a global effect. Place a 'begin' marker in the visible // set to indicate the effect is active. rCuller.Insert(mEffects[i], NULL); } GetVisibleSetRenderObject(rCuller, noCull); // All RenderObjects in the subtree are added to the visible set. If // a global effect is active, the RenderObjects in the subtree will be // drawn using it. for (UInt i = 0; i < mChildren.GetQuantity(); i++) { Spatial* pChild = mChildren[i]; if (pChild) { pChild->OnGetVisibleSet(rCuller, noCull); } } for (UInt i = 0; i < mEffects.GetQuantity(); i++) { // Place an 'end' marker in the visible set to indicate that the // global effect is inactive. rCuller.Insert(NULL, NULL); } }
/* ------------------------------------------------------- */ Object* SceneGraph::get(const String& root, const String& name) { Spatial* s = m_roots->get(root); if (!s) throw new Exception("root object not found in scene graph"); return s->getObject(name); }
void NavigationMeshInstance::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { Spatial *c = this; while (c) { navigation = c->cast_to<Navigation>(); if (navigation) { if (enabled && navmesh.is_valid()) { nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this); } break; } c = c->get_parent_spatial(); } if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { MeshInstance *dm = memnew(MeshInstance); dm->set_mesh(navmesh->get_debug_mesh()); if (is_enabled()) { dm->set_material_override(get_tree()->get_debug_navigation_material()); } else { dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); } add_child(dm); debug_view = dm; } } break; case NOTIFICATION_TRANSFORM_CHANGED: { if (navigation && nav_id != -1) { navigation->navmesh_set_transform(nav_id, get_relative_transform(navigation)); } } break; case NOTIFICATION_EXIT_TREE: { if (navigation) { if (nav_id != -1) { navigation->navmesh_remove(nav_id); nav_id = -1; } } if (debug_view) { debug_view->queue_delete(); debug_view = NULL; } navigation = NULL; } break; } }
void SpringArm::process_spring() { // From real_t motion_delta(1); real_t motion_delta_unsafe(1); Vector3 motion; const Vector3 cast_direction(get_global_transform().basis.xform(Vector3(0, 0, 1))); if (shape.is_null()) { motion = Vector3(cast_direction * (spring_length)); PhysicsDirectSpaceState::RayResult r; bool intersected = get_world()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask); if (intersected) { float dist = get_global_transform().origin.distance_to(r.position); dist -= margin; motion_delta = dist / (spring_length); } } else { motion = Vector3(cast_direction * spring_length); get_world()->get_direct_space_state()->cast_motion(shape->get_rid(), get_global_transform(), motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask); } current_spring_length = spring_length * motion_delta; Transform childs_transform; childs_transform.origin = get_global_transform().origin + cast_direction * (spring_length * motion_delta); for (int i = get_child_count() - 1; 0 <= i; --i) { Spatial *child = Object::cast_to<Spatial>(get_child(i)); if (child) { childs_transform.basis = child->get_global_transform().basis; child->set_global_transform(childs_transform); } } }
void Viewport::_propagate_exit_world(Node *p_node) { if (p_node!=this) { if (!p_node->is_inside_scene()) //may have exited scene already return; Spatial *s = p_node->cast_to<Spatial>(); if (s) { s->notification(Spatial::NOTIFICATION_EXIT_WORLD,false); } else { Viewport *v = p_node->cast_to<Viewport>(); if (v) { if (v->world.is_valid()) return; } } } for(int i=0;i<p_node->get_child_count();i++) { _propagate_exit_world(p_node->get_child(i)); } }
Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) { List<Ref<Mesh> > meshes; Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, Vector3(1, 1, 1), r_missing_deps); if (err != OK) { if (r_err) { *r_err = err; } return NULL; } Spatial *scene = memnew(Spatial); for (List<Ref<Mesh> >::Element *E = meshes.front(); E; E = E->next()) { MeshInstance *mi = memnew(MeshInstance); mi->set_mesh(E->get()); mi->set_name(E->get()->get_name()); scene->add_child(mi); mi->set_owner(scene); } if (r_err) { *r_err = OK; } return scene; }
//---------------------------------------------------------------------------- void Delaunay3D::DoSearch () { // Make all tetra wireframe. const int numSimplices = mDelaunay->GetNumSimplices(); Float4 lightGray(0.75f, 0.75f, 0.75f, 1.0f); int i; for (i = 0; i < numSimplices; ++i) { ChangeTetraStatus(i, lightGray, true); } // Generate random point in AABB of data set. Vector3f random; random.X() = Mathf::IntervalRandom(mMin.X(), mMax.X()); random.Y() = Mathf::IntervalRandom(mMin.Y(), mMax.Y()); random.Z() = Mathf::IntervalRandom(mMin.Z(), mMax.Z()); // Move sphere to this location. Spatial* sphere = mScene->GetChild(0); sphere->Culling = Spatial::CULL_DYNAMIC; sphere->LocalTransform.SetTranslate(random); sphere->Update(); if (mDelaunay->GetContainingTetrahedron(random) >= 0) { // Make all tetra on the path solid. const int pathLast = mDelaunay->GetPathLast(); for (i = 0; i <= pathLast; ++i) { int index = mDelaunay->GetPath()[i]; float red, blue; if (pathLast > 0) { red = i/(float)pathLast; blue = 1.0f - red; } else { red = 1.0f; blue = 0.0f; } ChangeTetraStatus(index, Float4(red, 0.0f, blue, 0.5f), false); } } else { // The point is outside the convex hull. Change the wireframe // color for the last visited face in the search path. int index = mDelaunay->GetPath()[mDelaunay->GetPathLast()]; int v0, v1, v2, v3; int vOpposite = mDelaunay->GetLastFace(v0, v1, v2, v3); ChangeLastTetraStatus(index, vOpposite, Float4(0.0f, 1.0f, 0.0f, 0.5f), Float4(0.0f, 0.25f, 0.0f, 0.5f)); } mCuller.ComputeVisibleSet(mScene); }
//---------------------------------------------------------------------------- Node* Game::LoadAndInitializeScene() { Importer importer("Data/Scene/"); Node* pScene = importer.LoadSceneFromXml("Scene.xml", mspPhysicsWorld); if (!pScene) { return NULL; } NodeCamera* pCameraNode = pScene->FindChild<NodeCamera>(); WIRE_ASSERT(pCameraNode /* No Camera in scene.xml */); mspSceneCamera = pCameraNode->Get(); mSortingCuller.SetCamera(mspSceneCamera); // The maximum number of objects that are going to be culled is the // number of objects we imported. If we don't set the size of the set now, // the culler will dynamically increase it during runtime. This is not // a big deal, however it is better to avoid memory allocations during the // render loop. UInt renderObjectCount = importer.GetStatistics()->RenderObjectCount; mSortingCuller.SetMaxQuantity(renderObjectCount); // Create and configure probe robot controller SpatialPtr spRedHealthBar = mspGUI->FindChild("RedHealthBar"); WIRE_ASSERT(spRedHealthBar /* No RedHealthBar in GUI.xml */); Node* pProbeRobotSpatial = DynamicCast<Node>(pScene->FindChild("Probe Robot")); WIRE_ASSERT(pProbeRobotSpatial /* No Probe Robot in Scene.xml */); // Detach red energy/health bar and attach it robot probe as a billboard NodeBillboard* pBillboard = WIRE_NEW NodeBillboard; pProbeRobotSpatial->AttachChild(pBillboard); Node* pParent = DynamicCast<Node>(spRedHealthBar->GetParent()); WIRE_ASSERT(pParent); pParent->DetachChild(spRedHealthBar); pBillboard->AttachChild(spRedHealthBar); Spatial* pPlayerSpatial = pScene->FindChild("Player"); WIRE_ASSERT(pPlayerSpatial /* No Player in Scene.xml */); mspProbeRobot = WIRE_NEW ProbeRobot(mspPhysicsWorld, pPlayerSpatial, spRedHealthBar); pProbeRobotSpatial->AttachController(mspProbeRobot); // Create and configure player controller mspPlayer = WIRE_NEW Player(mspSceneCamera, mspPhysicsWorld); pPlayerSpatial->AttachController(mspPlayer); Spatial* pPlatform = pScene->FindChild("Platform"); WIRE_ASSERT(pPlatform /* Platform object missing in scene */); pPlatform->AttachController(WIRE_NEW Elevator(mspPhysicsWorld)); pScene->Bind(GetRenderer()); pScene->WarmUpRendering(GetRenderer()); return pScene; }
int main() { Compass testCompass; InterfaceKit ifKit; LCD lcd; Motor motor; Spatial spatial; CPhidgetManagerHandle device = 0; LocalErrorCatcher( CPhidgetManager_create(&device)); LocalErrorCatcher( CPhidgetManager_set_OnAttach_Handler((CPhidgetManagerHandle) device, AttachHandler, NULL)); LocalErrorCatcher( CPhidgetManager_set_OnDetach_Handler((CPhidgetManagerHandle ) device, DetachHandler, NULL)); LocalErrorCatcher( CPhidgetManager_set_OnError_Handler((CPhidgetManagerHandle) device, LibraryErrorHandler, NULL)); printf("Starting Phidget Playground...\n"); // Most opening and closing would be via a cast to // (CPhidgetHandle), however, this manager has its // own handle struct to cast to. LocalErrorCatcher( CPhidgetManager_open((CPhidgetManagerHandle) device)); std::stringstream ss; lcd.clear(); for(int i=0;i<1000;i++){ testCompass.refresh(); ss << std::fixed << std::setprecision(1) << "Heading: " << testCompass.getHeading(); lcd.setText(ss.str(), 0); ss.str(std::string()); ss << std::fixed << std::setprecision(2) << spatial.getAcceleration(AXIS_X) << " " << spatial.getAcceleration(AXIS_Y) << " " << spatial.getAcceleration(AXIS_Z); lcd.setText(ss.str(), 1); ss.str(std::string()); usleep(100000); } printf("Press Enter to end...\n"); getchar(); LocalErrorCatcher( CPhidgetManager_close((CPhidgetManagerHandle) device)); LocalErrorCatcher( CPhidgetManager_delete((CPhidgetManagerHandle) device)); return 0; }
void VisualInstance::_notification(int p_what) { switch(p_what) { case NOTIFICATION_ENTER_WORLD: { // CHECK ROOM Spatial * parent = get_parent_spatial(); Room *room=NULL; bool is_geom = cast_to<GeometryInstance>(); while(parent) { room = parent->cast_to<Room>(); if (room) break; if (is_geom && parent->cast_to<BakedLightSampler>()) { VS::get_singleton()->instance_geometry_set_baked_light_sampler(get_instance(),parent->cast_to<BakedLightSampler>()->get_instance()); break; } parent=parent->get_parent_spatial(); } if (room) { VisualServer::get_singleton()->instance_set_room(instance,room->get_instance()); } // CHECK SKELETON => moving skeleton attaching logic to MeshInstance /* Skeleton *skeleton=get_parent()?get_parent()->cast_to<Skeleton>():NULL; if (skeleton) VisualServer::get_singleton()->instance_attach_skeleton( instance, skeleton->get_skeleton() ); */ VisualServer::get_singleton()->instance_set_scenario( instance, get_world()->get_scenario() ); } break; case NOTIFICATION_TRANSFORM_CHANGED: { Transform gt = get_global_transform(); VisualServer::get_singleton()->instance_set_transform(instance,gt); } break; case NOTIFICATION_EXIT_WORLD: { VisualServer::get_singleton()->instance_set_scenario( instance, RID() ); VisualServer::get_singleton()->instance_set_room(instance,RID()); VisualServer::get_singleton()->instance_attach_skeleton( instance, RID() ); VS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() ); } break; } }
void GridMap::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { Spatial *c = this; while (c) { navigation = Object::cast_to<Navigation>(c); if (navigation) { break; } c = Object::cast_to<Spatial>(c->get_parent()); } last_transform = get_global_transform(); for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { _octant_enter_world(E->key()); } } break; case NOTIFICATION_TRANSFORM_CHANGED: { Transform new_xform = get_global_transform(); if (new_xform == last_transform) break; //update run for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { _octant_transform(E->key()); } last_transform = new_xform; } break; case NOTIFICATION_EXIT_WORLD: { for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { _octant_exit_world(E->key()); } navigation = NULL; //_queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS); //_update_octants_callback(); //_update_area_instances(); } break; case NOTIFICATION_VISIBILITY_CHANGED: { _update_visibility(); } break; } }
//---------------------------------------------------------------------------- void Node::UpdateState (TStack<GlobalState*>* akGStack, TStack<Light*>* pkLStack) { for (int i = 0; i < m_kChild.GetQuantity(); i++) { Spatial* pkChild = m_kChild[i]; if (pkChild) { pkChild->UpdateRS(akGStack,pkLStack); } } }
void SceneAsset::_AddEntity(Entity* entity) { sceneEntities.push_back(Bind(entity)); if (cullingSystem) { Spatial* s = entity->GetSpatial(); bool isCamera = (Component::GetComponentCatagory(s->GetClassID()) & Camera::Traits::GetCatagory()) == Camera::Traits::GetCatagory(); if (s) { if (!isCamera) cullingSystem->AddBody(s); s->_SetCullingSystem(cullingSystem); } } }
void Spatial::GeometricStateUpdate() { UpdateWorldTransform(); //Propogate World Bounds To Root { Spatial * parent = GetParentAs<Spatial>(); while (parent != NULL) { parent->UpdateWorldBound(); parent = parent->GetParentAs<Spatial>(); } //Propogate World Bounds To Root } }
//---------------------------------------------------------------------------- void Node::UpdateWorldData (double dAppTime) { Spatial::UpdateWorldData(dAppTime); for (int i = 0; i < m_kChild.GetQuantity(); i++) { Spatial* pkChild = m_kChild[i]; if (pkChild) { pkChild->UpdateGS(dAppTime,false); } } }
//---------------------------------------------------------------------------- void Node::UpdateState(States* pStates, Lights* pLights) { UpdateStateRenderObject(pStates, pLights); for (UInt i = 0; i < mChildren.GetQuantity(); i++) { Spatial* pChild = mChildren[i]; if (pChild) { pChild->UpdateRS(pStates, pLights); } } }
//---------------------------------------------------------------------------- void Node::UpdateWorldData(Double appTime, Bool updateControllers) { Spatial::UpdateWorldData(appTime, updateControllers); for (UInt i = 0; i < GetQuantity(); i++) { Spatial* pChild = mChildren[i]; if (pChild) { pChild->UpdateGS(appTime, false, updateControllers); } } }
/* ------------------------------------------------------- */ void SceneGraph::fillHash(Set<Serializable*>& roots) { if (m_roots) delete m_roots; m_roots = new HashTable<String, Spatial*>(int(roots.size()*1.3)); for (Array<Serializable*>::Iterator i = roots.begin(); i != false; i++) { Spatial* tmpSpatial = dynamic_cast<Spatial*>(*i); if (tmpSpatial) m_roots->insert(tmpSpatial->getName(), tmpSpatial); } }
void InterpolatedCamera::_notification(int p_what) { switch(p_what) { case NOTIFICATION_ENTER_SCENE: { if (get_scene()->is_editor_hint() && enabled) set_fixed_process(false); } break; case NOTIFICATION_PROCESS: { if (!enabled) break; if (has_node(target)) { Spatial *node = get_node(target)->cast_to<Spatial>(); if (!node) break; float delta = speed*get_process_delta_time(); Transform target_xform = node->get_global_transform(); Transform local_transform = get_transform(); local_transform = local_transform.interpolate_with(target_xform,delta); set_global_transform(local_transform); if (node->cast_to<Camera>()) { Camera *cam = node->cast_to<Camera>(); if (cam->get_projection()==get_projection()) { float new_near = Math::lerp(get_znear(),cam->get_znear(),delta); float new_far = Math::lerp(get_zfar(),cam->get_zfar(),delta); if (cam->get_projection()==PROJECTION_ORTHOGONAL) { float size = Math::lerp(get_size(),cam->get_size(),delta); set_orthogonal(size,new_near,new_far); } else { float fov = Math::lerp(get_fov(),cam->get_fov(),delta); set_perspective(fov,new_near,new_far); } } } } } break; } }
//---------------------------------------------------------------------------- void SwitchNode::GetVisibleSet (Culler& culler, bool noCull) { if (mActiveChild == SN_INVALID_CHILD) { return; } // All Visual objects in the active subtree are added to the visible set. Spatial* child = mChild[mActiveChild]; if (child) { child->OnGetVisibleSet(culler, noCull); } }
//---------------------------------------------------------------------------- void Node::DoPick (const Ray3x& rkRay, PickArray& rkResults) { if (WorldBound->TestIntersection(rkRay)) { for (int i = 0; i < m_kChild.GetQuantity(); i++) { Spatial* pkChild = m_kChild[i]; if (pkChild) { pkChild->DoPick(rkRay,rkResults); } } } }
//---------------------------------------------------------------------------- void Node::GetAllObjectsByName (const String& rkName, TArray<Object*>& rkObjects) { Spatial::GetAllObjectsByName(rkName,rkObjects); for (int i = 0; i < m_kChild.GetQuantity(); i++) { Spatial* pkChild = m_kChild[i]; if (pkChild) { pkChild->GetAllObjectsByName(rkName,rkObjects); } } }
void SceneAsset::_RemoveEntity(Entity* entity) { NEX_ASSERT(entity->GetScene() == this); if (cullingSystem) { Spatial* s = entity->GetSpatial(); bool isCamera = (Component::GetComponentCatagory(s->GetClassID()) & Camera::Traits::GetCatagory()) == Camera::Traits::GetCatagory(); if (s) { if (!isCamera) cullingSystem->RemoveBody(s); s->_SetCullingSystem(nullptr); } } EntityPtr e = Bind(entity); sceneEntities.remove(e); toUpdate.remove(e); }
//---------------------------------------------------------------------------- void Node::Unbind(Renderer* pRenderer) { for (UInt i = 0; i < GetQuantity(); i++) { Spatial* pSpatial = GetChild(i); if (pSpatial) { pSpatial->Unbind(pRenderer); } } if (pRenderer) { pRenderer->Unbind(mspRenderObject); } }
void VisualInstance::_notification(int p_what) { switch(p_what) { case NOTIFICATION_ENTER_WORLD: { // CHECK ROOM Spatial * parent = get_parent_spatial(); Room *room=NULL; while(parent) { room = parent->cast_to<Room>(); if (room) break; else parent=parent->get_parent_spatial(); } if (room) { VisualServer::get_singleton()->instance_set_room(instance,room->get_instance()); } // CHECK SKELETON Skeleton *skeleton=get_parent()?get_parent()->cast_to<Skeleton>():NULL; if (skeleton) VisualServer::get_singleton()->instance_attach_skeleton( instance, skeleton->get_skeleton() ); VisualServer::get_singleton()->instance_set_scenario( instance, get_world()->get_scenario() ); } break; case NOTIFICATION_TRANSFORM_CHANGED: { Transform gt = get_global_transform(); VisualServer::get_singleton()->instance_set_transform(instance,gt); } break; case NOTIFICATION_EXIT_WORLD: { VisualServer::get_singleton()->instance_set_scenario( instance, RID() ); VisualServer::get_singleton()->instance_set_room(instance,RID()); VisualServer::get_singleton()->instance_attach_skeleton( instance, RID() ); } break; } }
void Spatial::_propagate_visibility_changed() { notification(NOTIFICATION_VISIBILITY_CHANGED); emit_signal(SceneStringNames::get_singleton()->visibility_changed); _change_notify("visibility/visible"); #ifdef TOOLS_ENABLED if (data.gizmo.is_valid()) _update_gizmo(); #endif for (List<Spatial *>::Element *E = data.children.front(); E; E = E->next()) { Spatial *c = E->get(); if (!c || !c->data.visible) continue; c->_propagate_visibility_changed(); } }
//---------------------------------------------------------------------------- void Node::Draw (Renderer& rkRenderer, bool bNoCull) { if (m_spkEffect == 0) { for (int i = 0; i < m_kChild.GetQuantity(); i++) { Spatial* pkChild = m_kChild[i]; if (pkChild) { pkChild->OnDraw(rkRenderer,bNoCull); } } } else { // A "global" effect might require multipass rendering, so the Node // must be passed to the renderer for special handling. rkRenderer.Draw(this); } }
//---------------------------------------------------------------------------- Object* Node::GetObjectByID (unsigned int uiID) { Object* pkFound = Spatial::GetObjectByID(uiID); if (pkFound) { return pkFound; } for (int i = 0; i < m_kChild.GetQuantity(); i++) { Spatial* pkChild = m_kChild[i]; if (pkChild) { pkFound = pkChild->GetObjectByID(uiID); if (pkFound) { return pkFound; } } } return 0; }
//---------------------------------------------------------------------------- // name and unique id //---------------------------------------------------------------------------- Object* Node::GetObjectByName (const String& rkName) { Object* pkFound = Spatial::GetObjectByName(rkName); if (pkFound) { return pkFound; } for (int i = 0; i < m_kChild.GetQuantity(); i++) { Spatial* pkChild = m_kChild[i]; if (pkChild) { pkFound = pkChild->GetObjectByName(rkName); if (pkFound) { return pkFound; } } } return 0; }