void TransformComponent::AddChild(corgi::EntityRef& child, corgi::EntityRef& parent) { TransformData* child_data = GetComponentData(child); TransformData* parent_data = GetComponentData(parent); // If child is already someone else's child, break that link first. if (child_data->parent) { RemoveChild(child); } parent_data->children.push_back(*child_data); child_data->parent = parent; }
void TransformComponent::RemoveChild(corgi::EntityRef& child) { TransformData* child_data = GetComponentData(child); assert(child_data->parent); child_data->parent = corgi::EntityRef(); child_data->child_node.remove(); }
void RenderMeshComponent::RenderPrep(const CameraInterface& camera) { for (int pass = 0; pass < RenderPass_Count; pass++) { pass_render_list_[pass].clear(); } for (auto iter = component_data_.begin(); iter != component_data_.end(); ++iter) { RenderMeshData* rendermesh_data = GetComponentData(iter->entity); TransformData* transform_data = Data<TransformData>(iter->entity); float max_cos = cos(camera.viewport_angle()); vec3 camera_facing = camera.facing(); vec3 camera_position = camera.position(); // Put each entity into the list for each render pass it is // planning on participating in. for (int pass = 0; pass < RenderPass_Count; pass++) { if (rendermesh_data->pass_mask & (1 << pass)) { if (!rendermesh_data->visible) continue; // Check to make sure objects are inside the frustrum of our // view-cone before we draw: vec3 entity_position = transform_data->world_transform.TranslationVector3D(); vec3 pos_relative_to_camera = (entity_position - camera_position) + camera_facing * kFrustrumOffset; // Cache off the distance from the camera because we'll use it // later as a depth aproxamation. rendermesh_data->z_depth = (entity_position - camera.position()).LengthSquared(); // Are we culling this object based on the view angle? // If so, does this lie outside of our view frustrum? if ((rendermesh_data->culling_mask & (1 << CullingTest_ViewAngle)) && (vec3::DotProduct(pos_relative_to_camera.Normalized(), camera_facing.Normalized()) < max_cos)) { // The origin point for this mesh is not in our field of view. Cut // out early, and don't bother rendering it. continue; } // Are we culling this object based on view distance? If so, // is it far enough away that we should skip it? if ((rendermesh_data->culling_mask & (1 << CullingTest_Distance)) && rendermesh_data->z_depth > culling_distance_squared()) { continue; } pass_render_list_[pass].push_back( RenderlistEntry(iter->entity, &iter->data)); } } } std::sort(pass_render_list_[RenderPass_Opaque].begin(), pass_render_list_[RenderPass_Opaque].end()); std::sort(pass_render_list_[RenderPass_Alpha].begin(), pass_render_list_[RenderPass_Alpha].end(), std::greater<RenderlistEntry>()); }
corgi::ComponentInterface::RawDataUniquePtr RenderMeshComponent::ExportRawData( const corgi::EntityRef& entity) const { const RenderMeshData* data = GetComponentData(entity); if (data == nullptr) return nullptr; if (data->mesh_filename == "" || data->shader_filename == "") { // If we don't have a mesh filename or a shader, we can't be exported; // we were obviously created programatically. return nullptr; } flatbuffers::FlatBufferBuilder fbb; bool defaults = entity_manager_->GetComponent<CommonServicesComponent>() ->export_force_defaults(); fbb.ForceDefaults(defaults); auto source_file = (defaults || data->mesh_filename != "") ? fbb.CreateString(data->mesh_filename) : 0; auto shader = (defaults || data->shader_filename != "") ? fbb.CreateString(data->shader_filename) : 0; std::vector<unsigned char> render_pass_vec; for (int i = 0; i < RenderPass_Count; i++) { if (data->pass_mask & (1 << i)) { render_pass_vec.push_back(i); } } auto render_pass = fbb.CreateVector(render_pass_vec); std::vector<unsigned char> culling_mask_vec; for (int i = 0; i < CullingTest_Count; i++) { if (data->culling_mask & (1 << i)) { culling_mask_vec.push_back(i); } } auto culling_mask = data->culling_mask ? fbb.CreateVector(culling_mask_vec) : 0; RenderMeshDefBuilder builder(fbb); if (defaults || source_file.o != 0) { builder.add_source_file(source_file); } if (defaults || shader.o != 0) { builder.add_shader(shader); } if (defaults || render_pass.o != 0) { builder.add_render_pass(render_pass); } if (defaults || culling_mask.o != 0) { builder.add_culling(culling_mask); } fbb.Finish(builder.Finish()); return fbb.ReleaseBufferPointer(); }
void TransformComponent::CleanupEntity(corgi::EntityRef& entity) { // Remove and cleanup children, if any exist: TransformData* transform_data = GetComponentData(entity); if (transform_data) { for (auto iter = transform_data->children.begin(); iter != transform_data->children.end(); ++iter) { entity_manager_->DeleteEntity(iter->owner); } } }
void TransformComponent::UpdateWorldPosition(corgi::EntityRef& entity, const mathfu::mat4& transform) { TransformData* transform_data = GetComponentData(entity); transform_data->world_transform = transform * transform_data->GetTransformMatrix(); for (auto iter = transform_data->children.begin(); iter != transform_data->children.end(); ++iter) { UpdateWorldPosition(iter->owner, transform_data->world_transform); } }
corgi::ComponentInterface::RawDataUniquePtr PlayerComponent::ExportRawData( const corgi::EntityRef& entity) const { const PlayerData* data = GetComponentData(entity); if (data == nullptr) return nullptr; flatbuffers::FlatBufferBuilder fbb; PlayerDefBuilder builder(fbb); fbb.Finish(builder.Finish()); return fbb.ReleaseBufferPointer(); }
corgi::ComponentInterface::RawDataUniquePtr SimpleMovementComponent::ExportRawData(const corgi::EntityRef& entity) const { const SimpleMovementData* data = GetComponentData(entity); if (data == nullptr) return nullptr; flatbuffers::FlatBufferBuilder fbb; fplbase::Vec3 velocity(data->velocity.x(), data->velocity.y(), data->velocity.z()); fbb.Finish(CreateSimpleMovementDef(fbb, &velocity)); return fbb.ReleaseBufferPointer(); }
corgi::ComponentInterface::RawDataUniquePtr TransformComponent::ExportRawData( const corgi::EntityRef& entity) const { const TransformData* data = GetComponentData(entity); if (data == nullptr) return nullptr; flatbuffers::FlatBufferBuilder fbb; bool defaults = entity_manager_->GetComponent<CommonServicesComponent>() ->export_force_defaults(); fbb.ForceDefaults(defaults); mathfu::vec3 euler = data->orientation.ToEulerAngles() / kDegreesToRadians; fplbase::Vec3 position(data->position.x(), data->position.y(), data->position.z()); fplbase::Vec3 scale(data->scale.x(), data->scale.y(), data->scale.z()); fplbase::Vec3 orientation(euler.x(), euler.y(), euler.z()); std::vector<flatbuffers::Offset<flatbuffers::String>> child_ids_vector; for (auto iter = data->child_ids.begin(); iter != data->child_ids.end(); ++iter) { child_ids_vector.push_back(fbb.CreateString(*iter)); } auto child_ids = (defaults || child_ids_vector.size() > 0) ? fbb.CreateVector(child_ids_vector) : 0; TransformDefBuilder builder(fbb); builder.add_position(&position); builder.add_scale(&scale); builder.add_orientation(&orientation); if (defaults || child_ids_vector.size() > 0) { builder.add_child_ids(child_ids); } fbb.Finish(builder.Finish()); return fbb.ReleaseBufferPointer(); }