Teigha Visualize 具有一种映射机制,即使在没有映射坐标的情况下也能使用正确的纹理设置。在本教程中,我们将创建一个球体,并使用映射器设置纹理。
让我们看看如何创建一个球体。
假设我们有一个模型和一个数据库 ID。让我们获取数据库的指针,向此模型添加一个实体,并向其附加一个球体。
// Open database
OdTvDatabasePtr pTvDb = databaseId.openObject();
// Create entity
OdTvModelPtr modelPtr = modelId.openObject(OdTv::kForWrite);
OdTvEntityId entityId = modelPtr->appendEntity(OD_T("Ball"));
OdTvEntityPtr pEntity = entityId.openObject(OdTv::kForWrite);
// Append sphere to entity
pEntity->appendShellFromSphere(OdTvPoint(3., 3., 3.), 0.9, OdTvVector::kYAxis, OdTvVector::kXAxis, 50);
然后创建材质和材质贴图,并将其设置为实体:
// Create material with unique name
OdTvMaterialId materialId = pTvDb->createMaterial("Material");
OdTvMaterialPtr pMaterial = materialId.openObject(OdTv::kForWrite);
// Create material map
OdTvMaterialMap materialMap;
// Set texture path to map
materialMap.setSourceFileName(“../resources/Ball.png”);
// Set material map to material
pMaterial->setDiffuse(OdTvMaterialColor(OdTvColorDef(255, 0, 0)), materialMap);
// Set material to mapper
pEntity->setMaterial(materialId);
映射投影类型设置为实体映射器。它显示了纹理如何与几何体关联。实体具有默认映射器和默认投影 kPlanar。
没有映射器的纹理:
在这种情况下,映射器类型为 kSphere。
映射器有两种:
- 设置为实体(OdTvMapperDef),用于纹理的平移、旋转和缩放。
- 用于漫反射贴图(OdTvMapper),用于纹理的偏移、缩放和旋转。
它们每个都有一个变换矩阵,但这些矩阵具有不同的功能。OdTvMapperDef 变换矩阵用于设置纹理在 3D 对象上的位置。平移向量在 3D 系统中平移纹理 UV 零点位置。例如,对于球体,它可以是球体的中心。此外,通过在另一个矩阵位置设置数据,纹理可以绕轴旋转。实体映射器的变换矩阵通常是变换矩阵,因此其元素与用于 3D 的普通矩阵的元素相同。
OdTvMapper 中的变换矩阵用于在对象上偏移、缩放和旋转纹理。在该矩阵的 [0][0] 位置,为 1 / u_scale;在 [1][1] 位置,为 1 / v_scale。为了将纹理完全设置在球体上,[0][0] 和 [1][1] 位置应为 1。纹理偏移在 [0][3] 处按 X 偏移,在 [1][3] 处按 Y 偏移。对于 X,偏移计算为 x * 1 / u_scale;对于 Y,偏移计算为 y * 1 / v_scale。对于旋转,在 [0][0] 处设置 cos([0][0]),在 [0][1] 处设置 sin([0][1])(顺时针)或 –sin([0][0])(逆时针),在 [1][0] 处设置 –sin([1][1])(顺时针)或 sin([1][1])(逆时针),在 [1][1] 处设置 cos([1][1])。只有当纹理缩放大于 1 时,偏移才有意义。
有许多方法可以简化映射器的使用:
- OdTvMapperDef::translate() 设置纹理位置。
- OdTvMapperDef::rotate() 旋转纹理。
- OdTvMapperDef::scale() 按轴缩放纹理。
- OdTvTextureMapper::setSampleSize() 设置纹理采样大小。
- OdTvTextureMapper::setOffset() 偏移纹理。
- OdTvTextureMapper::setRotation() 旋转纹理。
// Create material with unique name
OdTvMaterialId materialId = pTvDb->createMaterial("Material");
OdTvMaterialPtr pMaterial = materialId.openObject(OdTv::kForWrite);
// Create material map
OdTvMaterialMap materialMap;
// Create path to texture image file and set it to map
materialMap.setSourceFileName(“../resources/Ball.png”);
// Create entity mapper
OdTvMapperDef entityMapper;
entityMapper.setProjection(OdTvMapperDef::kSphere);
// Translate and rotate texture
entityMapper.translate(3., 3., 3.);
entityMapper.rotate(0., OdaPI / 2., OdaPI / 2.);
// Create material mapper, set texture sample size and set it to map
OdTvTextureMapper materialMapper;
materialMapper.setSampleSize(1., 1.);
materialMap.setMapper(materialMapper);
// Set mapper to entity
pEntity->setEntityMaterialMapper(entityMapper);
// Set material map to material
pMaterial->setDiffuse(OdTvMaterialColor(OdTvColorDef(255, 0, 0)), materialMap);
// Set material to mapper
pEntity->setMaterial(materialId);
结果是带有 kSphere 映射器的以下纹理: