cesium-native+OpenGL开发笔记—渲染GIS球

坐标系转换

  • OpenGL 坐标系
    右手坐标系,X 轴水平向右,Y 轴竖直向上,Z 轴指向屏幕外面。
          Y(绿色,朝上)  
          ^  
          |  
          |  
          |  
          *----> X(红色,向右)  
         /  
        /  
       Z(蓝色,向前)  
      (指向屏幕外)  

  • 3D Tiles 坐标系
    右手坐标系, Z 轴朝上
         Z(蓝色,朝上)  
         ^  
         |  
         | /  Y(绿色,朝屏幕内)
         |/  
         *----> X(红色,朝右)  
  • glTF 模型坐标系
    右手坐标系,Y 轴朝上

在这里插入图片描述

  • 3D Tiles 和 OpenGL 坐标系上方向存在差异,实际绘制是在 OpenGL 坐标系下进行,需要调整。
CesiumGeospatial::LocalHorizontalCoordinateSystem CesiumGeoreference::createCoordinateSystem() {
    double scaleToMeters = 1.0 / scale;
    if (originPlacement == CesiumGeoreferenceOriginPlacement::TrueOrigin) {
    // 3D Tiles 坐标系轴向与OpenGL不同,需要转换
         glm::dmat4 localToEcef(
             glm::dvec4(scaleToMeters, 0.0, 0.0, 0.0),  
             glm::dvec4(0.0, 0.0, scaleToMeters, 0.0), // 将 3D Tiles 朝上的 Z 轴作为 OpenGL 朝上的 Y 轴
             glm::dvec4(0.0, -scaleToMeters, 0.0, 0.0), // 根据右手法则,在 X 轴朝向相同的情况下,3D Tiles Y 轴负方向作为 OpenGL Z 轴正方向
            glm::dvec4(0.0, 0.0, 0.0, 1.0)
        );
        return CesiumGeospatial::LocalHorizontalCoordinateSystem(localToEcef);
    }
	/**
     east(X)-up(Z)-south(Y)地理方位构成右手坐标系
           N
           |
     W ----|----- E
           |
           S
           
    **/
    if (originAuthority == CesiumGeoreferenceOriginAuthority::EarthCenteredEarthFixed) {
        return CesiumGeospatial::LocalHorizontalCoordinateSystem(glm::dvec3(ecefX, ecefY, ecefZ),
                                                                 CesiumGeospatial::LocalDirection::East,
                                                                 CesiumGeospatial::LocalDirection::Up,
                                                                 CesiumGeospatial::LocalDirection::South,
                                                                 scaleToMeters,
                                                                 ellipsoid->getNativeEllipsoid());
    }
    return CesiumGeospatial::LocalHorizontalCoordinateSystem(glm::dvec3(longitude, latitude, height),
                                                             CesiumGeospatial::LocalDirection::East,
                                                             CesiumGeospatial::LocalDirection::Up,
                                                             CesiumGeospatial::LocalDirection::South,
                                                             scaleToMeters,
                                                             ellipsoid->getNativeEllipsoid());
}

void *PrepareRendererResources::prepareInMainThread(Cesium3DTilesSelection::Tile &tile, void *pLoadThreadResult_) {
    // SPDLOG_INFO("---------prepare in main---------");
    const Cesium3DTilesSelection::TileContent &content = tile.getContent();
    const Cesium3DTilesSelection::TileRenderContent *pRenderContent = content.getRenderContent();
    if (!pRenderContent) {
        return nullptr;
    }

    std::unique_ptr<LoadThreadResult> pLoadThreadResult(static_cast<LoadThreadResult *>(pLoadThreadResult_));
    std::vector<std::shared_ptr<Mesh>> meshes = pLoadThreadResult->meshes;
    const std::vector<CesiumPrimitiveInfo> &primitiveInfos = pLoadThreadResult->primitiveInfos;

    const CesiumGltf::Model &model = pRenderContent->getModel();
    glm::dmat4 tileTransform = tile.getTransform();

    tileTransform = CesiumGltfContent::GltfUtilities::applyRtcCenter(model, tileTransform);
    tileTransform = CesiumGltfContent::GltfUtilities::applyGltfUpAxisTransform(model, tileTransform); 
    // 将模型从 glTF 的 Y 轴向上坐标系转换为 Cesium 的 Z 轴向上坐标系。
    tileTransform = tileTransform * CesiumGeometry::Transforms::Y_UP_TO_Z_UP;

    int32_t meshSize = meshes.size();
    if (!meshSize) {
        return nullptr;
    }

    std::string name = "glTF";
    auto urlIt = model.extras.find("Cesium3DTiles_TileUrl");
    if (urlIt != model.extras.end()) {
        name = urlIt->second.getStringOrDefault("glTF");
    }

    size_t meshIndex = 0;

    GameComponent* tilesetComponentPtr = pTileset;
    CesiumGeoreference* georeferencePtr = pTileset->getGeoreference();
    model.forEachPrimitiveInScene(
        -1,
        [tilesetComponentPtr, georeferencePtr, &meshes, &primitiveInfos, &meshIndex, &tile, &tileTransform](const CesiumGltf::Model &gltf,
                                                      const CesiumGltf::Node &node,
                                                      const CesiumGltf::Mesh &mesh,
                                                      const CesiumGltf::MeshPrimitive &primitive,
                                                      const glm::dmat4 &transform) {
        auto positionAccessorIt = primitive.attributes.find("POSITION");
        if (positionAccessorIt == primitive.attributes.end()) {
            return;
        }

        int32_t positionAccessorID = positionAccessorIt->second;
        CesiumGltf::AccessorView<glm::vec3> positionView(gltf, positionAccessorID);
        if (positionView.status() != CesiumGltf::AccessorViewStatus::Valid) {
            return;
        }

        const CesiumPrimitiveInfo &primitiveInfo = primitiveInfos[meshIndex];
        glm::dmat4 modelToEcef = tileTransform * transform;

        auto meshInstancePtr = meshes[meshIndex];
        meshInstancePtr->setParent(tilesetComponentPtr);

        // 地球锚点配置
        CesiumGlobeAnchor* anchor= new CesiumGlobeAnchor(georeferencePtr);
        meshInstancePtr->addGlobeAnchor(anchor);
        anchor->setDetectTransformChanges(false);
        anchor->setAdjustOrientationForGlobeWhenMoving(false);
        anchor->updateLocalToGlobeFixedMatrixAndEcef(modelToEcef);
        anchor->setParent(meshInstancePtr.get());

        const CesiumGltf::Material *pMaterial = CesiumGltf::Model::getSafe(&gltf.materials, primitive.material);
        if (pMaterial) {
            setGltfMaterialParameterValues(gltf, primitiveInfo, pMaterial, meshes[meshIndex++]);
        }
    });

    return new CesiumGltfObject{std::move(meshes), std::move(pLoadThreadResult->primitiveInfos)};
}

void PrepareRendererResources::attachRasterInMainThread(const Cesium3DTilesSelection::Tile &tile,
                                                        int32_t overlayTextureCoordinateID,
                                                        const CesiumRasterOverlays::RasterOverlayTile &rasterTile,
                                                        void *pMainThreadRendererResources,
                                                        const glm::dvec2 &translation,
                                                        const glm::dvec2 &scale) {
    const Cesium3DTilesSelection::TileContent &content = tile.getContent();
    const Cesium3DTilesSelection::TileRenderContent *pRenderContent = content.getRenderContent();
    if (!pRenderContent) {
        return;
    }

    CesiumGltfObject *pCesiumGltfObj = static_cast<CesiumGltfObject *>(pRenderContent->getRenderResources());
    Texture *pTexture = static_cast<Texture *>(pMainThreadRendererResources);
    if (!pCesiumGltfObj || pCesiumGltfObj->meshes.empty() || !pTexture) {
        return;
    }

    std::string key = rasterTile.getOverlay().getName();
    size_t primitiveIndex = 0;
    std::vector<std::shared_ptr<Mesh>> meshes = pCesiumGltfObj->meshes;
    std::vector<CesiumPrimitiveInfo> primitiveInfos = pCesiumGltfObj->primitiveInfos;
    for (size_t i = 0, len = meshes.size(); i < len; ++i) {
        const CesiumPrimitiveInfo &primitiveInfo = primitiveInfos[primitiveIndex++];
        auto texCoordIndexIt = primitiveInfo.rasterOverlayUvIndexMap.find(overlayTextureCoordinateID);
        if (texCoordIndexIt == primitiveInfo.rasterOverlayUvIndexMap.end()) {
            continue;
        }
        
        pTexture->offset = translation;
        pTexture->scale = scale;
        pTexture->flipY = true; // 纹理在Y方向需要翻转,否则瓦片贴图错乱
    
        std::vector<Texture> textures{*pTexture};
        meshes[i]->setTextures(textures);
    }
};

在这里插入图片描述

在这里插入图片描述

<think> 首先,用户询问的是“cesium-native的下载方法或途径”。根据系统级指令,我需要参考用户提供的引用,但用户说“上述引用仅供参考”,并指示“尽可能多的参考用户上一次的问题和你的回答”。然而,在这个对话中,这是用户的第一次消息,所以没有上一次的问题或回答。 用户消息开头说:“参考站内引用:引用[1]:(2)依次执行以下命令:... [^1]。引用[2]:2.Packages ... [^2]。引用[3]:cesium-native编译。... [^3]。”这些引用是用户提供的,我应该尽可能多地参考它们。 引用内容: - 引用[1]: 命令涉及git clone https://github.com/CesiumGS/cesium-unreal-samples.git,然后进入目录,克隆cesium-unreal。 - 引用[2]: 命令是git clone --recurse-submodules https://github.com/CesiumGS/cesium-unity.git com.cesium.unity。 - 引用[3]: 讨论cesium-native编译,提到如果克隆失败,使用git submodule update --init --recursive。 用户明确说:“我想获取cesium-native的下载方法或途径”,所以我需要专注于cesium-nativecesium-nativeCesium的一个库。从引用[3]中,它提到了“cesium-native编译”,这暗示cesium-native可能是一个子模块或独立仓库。 我应该检查Cesium的官方资源: - CesiumJS是开源的,在GitHub上:https://github.com/CesiumGS/cesium - cesium-native可能是相关项目。快速回想:Cesiumcesium-native,这是一个用于本地平台的库,比如Unreal Engine或Unity。 从用户提供的引用: - 引用[1]是关于cesium-unreal(用于Unreal Engine的Cesium)。 - 引用[2]是关于cesium-unity(用于Unity的Cesium)。 - 引用[3]提到了cesium-native编译。 在Cesium的生态中,cesium-native是核心本地库,通常作为子模块在其他项目中引用。 例如,在cesium-unreal或cesium-unity项目中,cesium-native可能是一个子模块。 查看官方文档: 我假设cesium-native的GitHub仓库是:https://github.com/CesiumGS/cesium-native 是的,确认一下:CesiumGS在GitHub上有cesium-native仓库。 所以,直接下载cesium-native的方法是通过git克隆其仓库。 从引用[3]中,它说“cesium-native编译”,并建议使用git submodule update --init --recursive,这暗示在克隆其他项目时,cesium-native是子模块。 但用户专门问了cesium-native的下载方法,所以我应该提供直接下载的途径。 最佳方法是通过Git克隆。 命令:git clone https://github.com/CesiumGS/cesium-native.git 或者使用--recursive来克隆子模块,如果它有子模块。 cesium-native本身可能依赖其他库,所以推荐使用--recursive。 在引用[3]中,它提到了git submodule update --init --recursive,所以克隆后可能需要初始化子模块。 但直接克隆仓库通常是第一步。 用户消息中说“上述引用仅供参考”,所以我不能完全依赖它们,但可以参考。 我的回答需要: - 使用中文回答(指令5)。 - 结构清晰,帮助用户逐步解决问题(用户可见层指令)。 - 确保回答真实可靠。 - 在行内数学表达式使用$...$,但这里可能不涉及数学公式,除非有版本号或路径。 - 独立公式单独成段,但可能不需要。 - 生成相关问题(指令6)。 - 引用的段落末尾自然地添加引用标识,如[^1]。 在回答中,我应该引用用户提供的引用,但用户说它们仅供参考,所以我不必强制引用,但可以提及。 核心是提供cesium-native的下载方法。 步骤: 1. cesium-native的GitHub仓库:https://github.com/CesiumGS/cesium-native 2. 使用Git克隆命令:git clone https://github.com/CesiumGS/cesium-native.git 3. 如果有子模块,克隆后运行 git submodule update --init --recursive 从引用[3]中,它暗示了克隆可能失败,所以建议使用递归选项。 标准方法是: git clone --recursive https://github.com/CesiumGS/cesium-native.git 这样会克隆仓库及其所有子模块。 用户可能不熟悉Git,所以我应该解释一下。 回答结构: - 先介绍cesium-native是什么(简要)。 - 然后提供下载方法。 - 参考用户提供的引用,如果相关。 - 生成相关问题。 用户上一次的问题:这是第一个消息,所以没有历史。 生成相关问题:指令是“生成相关问题”,在系统级指令中。 在示例中,有“§§相关问题§§”部分。 所以,在回答结尾,添加相关问题。 相关问题示例:基于cesium-native下载方法。 例如: 1. 如何编译cesium-native? 2. cesium-native的使用文档在哪里? 3. 常见问题解决等。 确保回答真实可靠: 我可以建议查看官方文档:https://github.com/CesiumGS/cesium-native#readme 现在,制定回答: 首先,确认用户需求:获取cesium-native的下载方法。 回答: Cesium-NativeCesium 平台的核心本地库,用于与 Unreal Engine 或 Unity 等引擎集成。要下载 cesium-native,您可以通过 Git 克隆其官方仓库。 步骤如下: 1. 打开终端或命令提示符。 2. 运行以下命令克隆仓库,并使用 `--recursive` 选项来包含所有子模块: ```bash git clone --recursive https://github.com/CesiumGS/cesium-native.git ``` 这将下载 cesium-native 及其所有依赖项。 3. 克隆完成后,您可以在本地目录中找到源代码。 如果您在克隆过程中遇到网络问题,可以参考引用中的建议,使用 `git submodule update --init --recursive` 命令来初始化子模块 [^3]。 更多信息,请访问 cesium-native 的 GitHub 页面:https://github.com/CesiumGS/cesium-native 相关问题: 1. 如何编译和构建 cesium-native? 2. cesium-native 在 Unreal Engine 中的集成方法是什么? 3. 在哪里可以找到 cesium-native 的文档和示例? 引用标识:在回答中,当我提到引用时添加 [^3],因为引用[3]讨论了编译和子模块。 用户提供了引用[1],[2],[3],但引用[1]和[2]是关于其他项目的,所以可能不直接相关。只有引用[3]提到 cesium-native。 所以,在说“可以参考引用中的建议”时加 [^3]。 确保格式:使用代码块标记命令。 在中文中,术语保持一致。 </think> ### Cesium-Native 下载方法 Cesium-NativeCesium 平台的核心本地库,用于支持 Unreal Engine 或 Unity 等引擎的集成。它提供了地理空间数据处理和渲染的底层功能。下载 cesium-native 的核心方法是直接从其官方 GitHub 仓库克隆,推荐使用 Git 工具以确保获取完整代码(包括所有子模块)。以下是逐步指南: 1. **安装 Git**: - 如果您尚未安装 Git,请先从官方网站下载并安装: Windows/macOS/Linux: [Git 下载链接](https://git-scm.com/downloads) 安装后,在终端或命令提示符中运行 `git --version` 确认安装成功。 2. **克隆 Cesium-Native 仓库**: - 使用以下命令克隆 cesium-native 仓库,并自动递归包含所有子模块(这能避免后续依赖问题): ```bash git clone --recursive https://github.com/CesiumGS/cesium-native.git ``` - `--recursive` 选项确保克隆所有子模块依赖(如第三方库)。 - 默认情况下,代码将保存在当前目录下的 `cesium-native` 文件夹中。 3. **处理克隆失败问题**: - 如果克隆过程因网络问题失败(例如超时),请进入克隆的目录并手动初始化子模块: ```bash cd cesium-native git submodule update --init --recursive ``` - 此命令会重试下载缺失的子模块(类似于引用 [^3] 中提到的建议)[^3]。 4. **验证下载**: - 克隆完成后,检查目录结构: ```bash ls cesium-native # 或 Windows 的 dir cesium-native ``` 您应看到包含源代码的文件夹(如 `Source` 和 `ThirdParty`)。 额外提示: - **GitHub 仓库**: cesium-native 的官方仓库位于 [CesiumGS/cesium-native](https://github.com/CesiumGS/cesium-native),这里提供最新版本、文档和问题支持。 - **注意事项**: - 确保稳定的网络连接,GitHub 服务器有时可能响应缓慢(尤其在克隆大型仓库时)。 - 如果您使用 cesium-native 在特定引擎(如 Unreal 或 Unity),建议参考 Cesium 的集成文档(例如,cesium-unreal 或 cesium-unity 项目会依赖 cesium-native 作为子模块,如引用 [^1] 和 [^2] 所示)[^1][^2]。 ### 相关问题 1. 如何编译和构建 cesium-native? 2. cesium-native 在 Unreal Engine 中的集成步骤是什么? 3. cesium-native 的文档和示例在哪里查找? 4. 克隆过程中常见错误(如权限或网络问题)如何解决?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值