void MoveComponent::update() { setSpeed(); collide(); // Stamp on the ground. Boxf characterFeet = Boxf( Vec2(_puppet->worldBox().min().x() + TILESIZE / 3.0, _puppet->worldBox().max().y() + 0.1 * COLLISION_DELTA), Vec2(_puppet->worldBox().max().x() - TILESIZE / 3.0, _puppet->worldBox().max().y() + 0.9 * COLLISION_DELTA)); CollisionList intersections = _obj->scene()->level().collide(0, characterFeet); float amount = 0.0; for (Boxf collision: intersections) amount += collision.volume(); if (amount > 0.9 * characterFeet.volume()) _airTime = 0; else if (!_airTime && !_ladder) _airTime = 1; // Check ladder. if (!onLadder()) _ladder = false; }
void PhysWorld3D::ForEachBodyInAABB(const Boxf& box, const BodyIterator& iterator) { auto NewtonCallback = [](const NewtonBody* const body, void* const userdata) -> int { const BodyIterator& bodyIterator = *static_cast<BodyIterator*>(userdata); return bodyIterator(*static_cast<RigidBody3D*>(NewtonBodyGetUserData(body))); }; NewtonWorldForEachBodyInAABBDo(m_world, box.GetMinimum(), box.GetMaximum(), NewtonCallback, const_cast<void*>(static_cast<const void*>(&iterator))); }
bool BoxBoxIntersection(const Boxf& a, const Boxf& b) { Vec2f minA = a.GetMin(); Vec2f maxA = a.GetMax(); Vec2f minB = b.GetMin(); Vec2f maxB = b.GetMax(); if ((maxA.y < minB.y) || (minA.y > maxB.y) || (maxA.x < minB.x) || (minA.x > maxB.x)) return false; return true; }
bool isCenterInViewport(const Frustum& frustum, const Boxf& worldBox, const Viewport& viewport) const { Vector4f center = worldBox.getCenter(); center[3] = 1.0; Vector4f mvpCenter = frustum.getMVPMatrix() * center; Vector3f mvpCenterHom = mvpCenter / mvpCenter[3]; const bool isNegXBorder = viewport[0] == 0.0f; // left const bool isPosXBorder = viewport[0] + viewport[2] == 1.0f; // left + width const bool isNegYBorder = viewport[1] == 0.0f; // top const bool isPosYBorder = viewport[1] + viewport[3] == 1.0f; // top + height Vector3f minBox(-1.0f); Vector3f maxBox(1.0f); if (isNegXBorder) minBox[0] = -infinite; if (isPosXBorder) maxBox[0] = infinite; if (isNegYBorder) minBox[1] = -infinite; if (isPosYBorder) maxBox[1] = infinite; minBox[2] = -infinite; maxBox[2] = infinite; const Boxf ndcCube(minBox, maxBox); return ndcCube.isIn(mvpCenterHom); }
bool MoveComponent::onLadder() { Boxf characterFeet = Boxf( Vec2(_puppet->worldBox().min().x() + TILESIZE / 3.0, _puppet->worldBox().max().y() - 1.9 * COLLISION_DELTA), Vec2(_puppet->worldBox().max().x() - TILESIZE / 3.0, _puppet->worldBox().max().y() - 1.1 * COLLISION_DELTA)); CollisionList intersections = _obj->scene()->level().collide(1, characterFeet, true); float amount = 0.0; for (Boxf collision: intersections) amount += collision.volume(); if (amount > 0.6 * characterFeet.volume()) return true; return false; }
void TriggerComponent::update() { _obj->sprite->setTileIndex( tileEnable + (_animCounter / animSpeed) % animCount); Boxf pBox = _state->player()->worldBox(); Boxf wBox = _obj->worldBox(); if(!hitPoint.empty()) { Vec2 point = wBox.min() + pointCoords; if(pBox.contains(point)) { _state->exec(hitPoint.c_str()); } } if(!hit.empty()) { if(!pBox.intersection(wBox).isEmpty()) { _state->exec(hit.c_str()); } } bool doUse = _state->input().justPressed(_state->useInput()); if(!use.empty() && doUse) { Vec2 usePoint = pBox.center(); if(wBox.contains(usePoint)) { _state->exec(use.c_str()); } } ++_animCounter; }
void Mesh::Recenter() { #if NAZARA_UTILITY_SAFE if (!m_impl) { NazaraError("Mesh not created"); return; } if (m_impl->animationType != AnimationType_Static) { NazaraError("Mesh must be static"); return; } #endif // Le centre de notre mesh est le centre de l'AABB *globale* Vector3f center = GetAABB().GetCenter(); for (SubMesh* subMesh : m_impl->subMeshes) { StaticMesh* staticMesh = static_cast<StaticMesh*>(subMesh); BufferMapper<VertexBuffer> mapper(staticMesh->GetVertexBuffer(), BufferAccess_ReadWrite); MeshVertex* vertices = static_cast<MeshVertex*>(mapper.GetPointer()); unsigned int vertexCount = staticMesh->GetVertexCount(); for (unsigned int i = 0; i < vertexCount; ++i) { vertices->position -= center; vertices++; } // l'AABB ne change pas de dimensions mais seulement de position, appliquons-lui le même procédé Boxf aabb = staticMesh->GetAABB(); aabb.Translate(-center); staticMesh->SetAABB(aabb); } // Il ne faut pas oublier d'invalider notre AABB m_impl->aabbUpdated = false; }
void ForwardRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { if (material->IsEnabled(RendererParameter_Blend)) { Layer& currentLayer = GetLayer(renderOrder); auto& transparentModels = currentLayer.transparentModels; auto& transparentModelData = currentLayer.transparentModelData; // Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant) unsigned int index = transparentModelData.size(); transparentModelData.resize(index+1); TransparentModelData& data = transparentModelData.back(); data.material = material; data.meshData = meshData; data.squaredBoundingSphere = Spheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); data.transformMatrix = transformMatrix; transparentModels.push_back(index); } else { Layer& currentLayer = GetLayer(renderOrder); auto& opaqueModels = currentLayer.opaqueModels; auto it = opaqueModels.find(material); if (it == opaqueModels.end()) { BatchedModelEntry entry; entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; } BatchedModelEntry& entry = it->second; entry.enabled = true; auto& meshMap = entry.meshMap; auto it2 = meshMap.find(meshData); if (it2 == meshMap.end()) { MeshInstanceEntry instanceEntry; instanceEntry.squaredBoundingSphere = meshAABB.GetSquaredBoundingSphere(); if (meshData.indexBuffer) instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &ForwardRenderQueue::OnIndexBufferInvalidation); instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &ForwardRenderQueue::OnVertexBufferInvalidation); it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; } std::vector<Matrix4f>& instances = it2->second.instances; instances.push_back(transformMatrix); // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau } }
void DebugDrawer::Draw(const Boxf& box) { if (!Initialize()) { NazaraError("Failed to initialize Debug Drawer"); return; } BufferMapper<VertexBuffer> mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 24); VertexStruct_XYZ* vertex = reinterpret_cast<VertexStruct_XYZ*>(mapper.GetPointer()); Vector3f max, min; max = box.GetMaximum(); min = box.GetMinimum(); vertex->position.Set(min.x, min.y, min.z); vertex++; vertex->position.Set(max.x, min.y, min.z); vertex++; vertex->position.Set(min.x, min.y, min.z); vertex++; vertex->position.Set(min.x, max.y, min.z); vertex++; vertex->position.Set(min.x, min.y, min.z); vertex++; vertex->position.Set(min.x, min.y, max.z); vertex++; vertex->position.Set(max.x, max.y, max.z); vertex++; vertex->position.Set(min.x, max.y, max.z); vertex++; vertex->position.Set(max.x, max.y, max.z); vertex++; vertex->position.Set(max.x, min.y, max.z); vertex++; vertex->position.Set(max.x, max.y, max.z); vertex++; vertex->position.Set(max.x, max.y, min.z); vertex++; vertex->position.Set(min.x, min.y, max.z); vertex++; vertex->position.Set(max.x, min.y, max.z); vertex++; vertex->position.Set(min.x, min.y, max.z); vertex++; vertex->position.Set(min.x, max.y, max.z); vertex++; vertex->position.Set(min.x, max.y, min.z); vertex++; vertex->position.Set(max.x, max.y, min.z); vertex++; vertex->position.Set(min.x, max.y, min.z); vertex++; vertex->position.Set(min.x, max.y, max.z); vertex++; vertex->position.Set(max.x, min.y, min.z); vertex++; vertex->position.Set(max.x, max.y, min.z); vertex++; vertex->position.Set(max.x, min.y, min.z); vertex++; vertex->position.Set(max.x, min.y, max.z); vertex++; mapper.Unmap(); Renderer::SetRenderStates(s_renderStates); Renderer::SetShader(s_shader); Renderer::SetVertexBuffer(&s_vertexBuffer); s_shader->SendColor(s_colorLocation, s_primaryColor); Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, 24); }