Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent) : mContext(aContext), mParent(aParent) { uint8_t header[8]; MediaByteRange headerRange(aOffset, aOffset + sizeof(header)); if (mParent && !mParent->mRange.Contains(headerRange)) { return; } const MediaByteRange* byteRange; for (int i = 0; ; i++) { if (i == mContext->mByteRanges.Length()) { return; } byteRange = &mContext->mByteRanges[i]; if (byteRange->Contains(headerRange)) { break; } } size_t bytes; if (!mContext->mSource->CachedReadAt(aOffset, header, sizeof(header), &bytes) || bytes != sizeof(header)) { return; } uint64_t size = BigEndian::readUint32(header); if (size == 1) { uint8_t bigLength[8]; MediaByteRange bigLengthRange(headerRange.mEnd, headerRange.mEnd + sizeof(bigLength)); if ((mParent && !mParent->mRange.Contains(bigLengthRange)) || !byteRange->Contains(bigLengthRange) || !mContext->mSource->CachedReadAt(aOffset, bigLength, sizeof(bigLength), &bytes) || bytes != sizeof(bigLength)) { return; } size = BigEndian::readUint64(bigLength); mBodyOffset = bigLengthRange.mEnd; } else { mBodyOffset = headerRange.mEnd; } mType = BigEndian::readUint32(&header[4]); mChildOffset = mBodyOffset + BoxOffset(mType); MediaByteRange boxRange(aOffset, aOffset + size); if (mChildOffset > boxRange.mEnd || (mParent && !mParent->mRange.Contains(boxRange)) || !byteRange->Contains(boxRange)) { return; } mRange = boxRange; }
Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent) : mContext(aContext), mParent(aParent) { uint8_t header[8]; if (aOffset > INT64_MAX - sizeof(header)) { return; } MediaByteRange headerRange(aOffset, aOffset + sizeof(header)); if (mParent && !mParent->mRange.Contains(headerRange)) { return; } const MediaByteRange* byteRange; for (int i = 0; ; i++) { if (i == mContext->mByteRanges.Length()) { return; } byteRange = &mContext->mByteRanges[i]; if (byteRange->Contains(headerRange)) { break; } } size_t bytes; if (!mContext->mSource->CachedReadAt(aOffset, header, sizeof(header), &bytes) || bytes != sizeof(header)) { return; } uint64_t size = BigEndian::readUint32(header); if (size == 1) { uint8_t bigLength[8]; if (aOffset > INT64_MAX - sizeof(header) - sizeof(bigLength)) { return; } MediaByteRange bigLengthRange(headerRange.mEnd, headerRange.mEnd + sizeof(bigLength)); if ((mParent && !mParent->mRange.Contains(bigLengthRange)) || !byteRange->Contains(bigLengthRange) || !mContext->mSource->CachedReadAt(aOffset + sizeof(header), bigLength, sizeof(bigLength), &bytes) || bytes != sizeof(bigLength)) { return; } size = BigEndian::readUint64(bigLength); mBodyOffset = bigLengthRange.mEnd; } else if (size == 0) { // box extends to end of file. size = mContext->mByteRanges.LastElement().mEnd - aOffset; mBodyOffset = headerRange.mEnd; } else { mBodyOffset = headerRange.mEnd; } if (size > INT64_MAX) { return; } int64_t end = static_cast<int64_t>(aOffset) + static_cast<int64_t>(size); if (end < static_cast<int64_t>(aOffset)) { // Overflowed. return; } mType = BigEndian::readUint32(&header[4]); mChildOffset = mBodyOffset + BoxOffset(mType); MediaByteRange boxRange(aOffset, end); if (mChildOffset > boxRange.mEnd || (mParent && !mParent->mRange.Contains(boxRange)) || !byteRange->Contains(boxRange)) { return; } mRange = boxRange; }
void TutorFramework::OnCreate() { font_ = KlayGE::SyncLoadFont("gkai00mp.kfont"); KlayGE::OBBox boxRange(KlayGE::MathLib::convert_to_obbox(KlayGE::AABBox(KlayGE::float3(-1.0f, -0.25f, -0.25f), KlayGE::float3(-0.5f, 0.25f, 0.25f)))); KlayGE::Color boxColor(1.0f, 0.0f, 0.0f, 1.0f); renderableBox_ = KlayGE::MakeSharedPtr<KlayGE::SceneObjectHelper>( KlayGE::MakeSharedPtr<KlayGE::RenderableTriBox>(boxRange, boxColor), KlayGE::SceneObject::SOA_Cullable); renderableBox_->AddToSceneManager(); KlayGE::RenderModelPtr loadedModel = KlayGE::SyncLoadModel("teapot.meshml", KlayGE::EAH_GPU_Read, KlayGE::CreateModelFactory<KlayGE::RenderModel>(), KlayGE::CreateMeshFactory<RenderPolygon>()); renderableFile_ = KlayGE::MakeSharedPtr<KlayGE::SceneObjectHelper>(loadedModel, KlayGE::SceneObject::SOA_Cullable); renderableFile_->ModelMatrix(KlayGE::MathLib::translation(0.0f, 0.5f, 0.0f)); renderableFile_->AddToSceneManager(); std::vector<KlayGE::float3> vertices; vertices.push_back(KlayGE::float3(0.5f,-0.25f, 0.25f)); vertices.push_back(KlayGE::float3(1.0f,-0.25f, 0.25f)); vertices.push_back(KlayGE::float3(1.0f,-0.25f,-0.25f)); vertices.push_back(KlayGE::float3(0.5f,-0.25f,-0.25f)); vertices.push_back(KlayGE::float3(0.5f, 0.25f, 0.25f)); vertices.push_back(KlayGE::float3(1.0f, 0.25f, 0.25f)); vertices.push_back(KlayGE::float3(1.0f, 0.25f,-0.25f)); vertices.push_back(KlayGE::float3(0.5f, 0.25f,-0.25f)); KlayGE::RenderModelPtr model = KlayGE::MakeSharedPtr<KlayGE::RenderModel>(L"model"); std::vector<KlayGE::StaticMeshPtr> meshes(2); std::vector<KlayGE::uint16_t> indices1; indices1.push_back(0); indices1.push_back(4); indices1.push_back(1); indices1.push_back(5); indices1.push_back(2); indices1.push_back(6); indices1.push_back(3); indices1.push_back(7); indices1.push_back(0); indices1.push_back(4); meshes[0] = KlayGE::MakeSharedPtr<RenderPolygon>(model, L"side_mesh"); meshes[0]->AddVertexStream(&vertices[0], static_cast<KlayGE::uint32_t>(sizeof(vertices[0]) * vertices.size()), KlayGE::vertex_element(KlayGE::VEU_Position, 0, KlayGE::EF_BGR32F), KlayGE::EAH_GPU_Read); meshes[0]->AddIndexStream(&indices1[0], static_cast<KlayGE::uint32_t>(sizeof(indices1[0]) * indices1.size()), KlayGE::EF_R16UI, KlayGE::EAH_GPU_Read); meshes[0]->GetRenderLayout().TopologyType(KlayGE::RenderLayout::TT_TriangleStrip); meshes[0]->PosBound(KlayGE::AABBox(KlayGE::float3(-1, -1, -1), KlayGE::float3(1, 1, 1))); std::vector<KlayGE::uint16_t> indices2; indices2.push_back(0); indices2.push_back(1); indices2.push_back(2); indices2.push_back(0); indices2.push_back(2); indices2.push_back(3); indices2.push_back(7); indices2.push_back(6); indices2.push_back(5); indices2.push_back(7); indices2.push_back(5); indices2.push_back(4); meshes[1] = KlayGE::MakeSharedPtr<RenderPolygon>(model, L"cap_mesh"); meshes[1]->AddVertexStream(&vertices[0], static_cast<KlayGE::uint32_t>(sizeof(vertices[0]) * vertices.size()), KlayGE::vertex_element(KlayGE::VEU_Position, 0, KlayGE::EF_BGR32F), KlayGE::EAH_GPU_Read); meshes[1]->AddIndexStream(&indices2[0], static_cast<KlayGE::uint32_t>(sizeof(indices2[0]) * indices2.size()), KlayGE::EF_R16UI, KlayGE::EAH_GPU_Read); meshes[1]->GetRenderLayout().TopologyType(KlayGE::RenderLayout::TT_TriangleList); meshes[1]->PosBound(KlayGE::AABBox(KlayGE::float3(-1, -1, -1), KlayGE::float3(1, 1, 1))); for (size_t i = 0; i < meshes.size(); ++ i) { meshes[i]->BuildMeshInfo(); } model->AssignSubrenderables(meshes.begin(), meshes.end()); renderableMesh_ = KlayGE::MakeSharedPtr<KlayGE::SceneObjectHelper>(model, KlayGE::SceneObject::SOA_Cullable); renderableMesh_->AddToSceneManager(); this->LookAt(KlayGE::float3(0, 0,-4.0f), KlayGE::float3(0, 0, 0)); this->Proj(0.1f, 20.0f); tbController_.AttachCamera(this->ActiveCamera()); tbController_.Scalers(0.01f, 0.05f); }