CGA 基础知识

坐标系

3D 坐标系用于描述物体在空间中的位置和方向。 虽然 CityEngine 可以处理许多不同类型的(地理配准)坐标系,但 CGA 建模仅适用于笛卡尔坐标系。 坐标系由其原点以及三个正交轴的方向定义。 虽然一个全球坐标系足以定义几何的每个折点,但是使用相对于彼此定义的坐标系层次结构更加实用。

以放置在街道路段上的汽车模型为例。 定义车轮相对于汽车以及汽车相对于街道的位置是有意义的。 汽车系统的原点和方向由街道系统的坐标定义。 由此,两个坐标系彼此相关,并且可以将一个系统的坐标转换为另一个系统的坐标。

处理形状时涉及多个坐标系。 将在由当前形状的范围(范围系统)定义的系统中进行上述所有转换。 还存在与每个形状相关联的枢轴系统,并且每个形状都定义了一个对象坐标系。

在 CGA 中,多个坐标系彼此相关:

世界坐标系

  • 针对场景定义。
  • 全局 - 每个场景仅存在一个。
  • 可以进行地理配准,但是无需执行此操作。
  • 将在世界坐标中定义初始形状的位置。

世界坐标系
对象坐标系

  • 针对每个初始形状定义的局部坐标系。
  • 原点放置在初始形状第一条边的第一个点处。
  • 轴的方向为 x 轴沿第一条边,y 轴沿第一个面的法线,z 轴垂直于前两个轴。

对象坐标系
枢轴坐标系

  • 将在对象坐标中介绍枢轴系统。
  • 在许多情况下,枢轴原点和方向与对象坐标相同。 但是,在组件分割等情况下它仍然发挥作用。

枢轴坐标系
范围坐标系

  • 范围类似于在枢轴系统中放置并定向的边界框。
  • 除了具有坐标系的特征外,范围还具有大小。 由宽度、高度和深度定义大小。
  • 借助变换,可以定义范围的位置、方向和大小。

范围坐标系
注:

  • 在开发 CGA 规则时,可以使用模型等级窗口来可视化模型的坐标系和形状。
  • 可以查询枢轴范围属性。

CGA 形状

CGA 形状是 CGA 形状语法的核心组成部分。 形状由定向边界框(范围)中的几何构成。 将相对于枢轴放置范围。

CGA 形状
在枢轴坐标系中所应用范围的平移和大小将定义几何的位置、大小和方向。
注:

初始形状将用作 CGA 规则的起始 CGA 形状。 请参阅形状

形状具有以下组成部分:

形状符号

形状的名称。 用于查找用于生成连续形状的匹配规则。

枢轴

枢轴描述形状的坐标系,并由以下内容定义:

  • 位置矢量 p(pivot.pxpivot.pypivot.pz
  • 方向矢量 o(pivot.oxpivot.oypivot.oz

将相对于初始形状的原点,以对象坐标给定枢轴;请参阅坐标系

范围

范围表示相对于枢轴的空间形状的定向边界框,并由三个矢量定义:

  • 平移矢量 t(scope.txscope.tyscope.tz
  • 旋转矢量 r(scope.rxscope.ryscope.rz
  • 大小矢量 s(scope.sxscope.syscope.sz

几何

几何包含有关构成形状类型的角、边和面的信息。 几何可以是任何类型的面网格。 此外,有关颜色、材料和纹理(着色器属性)的信息也存储在几何中。

参数

每个形状可以具有关联的参数列表。 将在创建形状的规则中隐式定义经过排序的参数列表。 支持以下三种参数类型:

  • 布尔
  • 数值(内部以双精度浮点数表示)
  • 字符串

规则应用

规则的基本目的是将具有特定形状符号的形状替换为许多新形状,例如:

PredecessorShape --> Successor

以下内容为简单示例:

A --> B

在具有符号 A 的特定形状上应用时,以上规则将创建该形状的副本并将其形状符号设置为 B。 A 形状视为已完成,不再进一步处理。 如果没有匹配符号 B 的规则,则生成过程结束。 生成的结构称为形状树,如下方示例所示:

形状树
形状树

在示例形状树中,A 为根形状,B 为叶形状。 叶形状十分重要,因为所有叶形状的总和表示生成的模型。 内部节点在最终模型中将不可见。

生成的模型
生成的模型

在此简单示例中,我们假定了形状 A 的几何并设置了其范围和枢轴,使形状表示位于原点的单位立方体。 因为 B 是 A 的副本,所以 B 的外观与其完全相同(请参见上图)。

规则可以具有更加复杂的后继,例如,规则的右侧可以包含多个形状符号和形状操作:

A --> B t(3, 0, 0) C

现在,将从左到右执行此后继。 同样,B 是 A 的相同副本。 随后,当前形状将沿 x 方向平移 3 个单位(即,对 scope.t 进行操作),并创建一个新形状 C。 形状树现在有两个叶子:

在树中创建的形状 C
在树中创建的形状 C

两个叶子 B 和 C 构成最终 3D 模型:

叶子 B 和 C 构成最终 3D 模型
叶子 B 和 C 构成最终 3D 模型

针对 C 添加此规则:

C --> D s(2, 0.5, 1.75) E

生成过程将为形状 C 添加两个子形状 D 和 E。 形状 D 是形状 C 的精确副本,但形状 E 的范围大小不同(由于 s() 形状操作)。 形状树和关联的模型如下所示:

已添加子形状 D 和 E 的模型
形状树以及已添加子形状 D 和 E 的模型
形状树以及已添加子形状 D 和 E 的模型
注:

现在,叶形状(B、D、E)不在同一级别上(即距根形状的距离不同),但是它们都是模型的一部分。

另一个形状操作是插入操作 i()

E --> i("cylinder.obj") F

再次开始生成后,形状 E 不再是叶形状,而是具有子形状 F。

具有子形状 F 的形状 E
具有子形状 F 的形状 E

形状 F 的几何不再是立方体,而是替换为从文件 "cylinder.obj" 中读取的网格。

注:

形状 F 的大小(即 scope.s 矢量)仍然与形状 E 的大小相同。

形状 F 与形状 E 大小相同
形状 F 与形状 E 大小相同

最终形状

在上方的 E 规则中,F 是所谓的最终形状:由于未定义 F 规则,因此将在此点处停止生成。 但是,CGA 编辑器将发出未定义规则的警告。 可以在 F 后添加一个句点以阻止此警告,此举会将 F 标记为最终形状:

E --> i("cylinder.obj") F.

匿名叶形状

为了方便起见,可以将上述 E 规则等规则截断:

E --> i("cylinder.obj")

在本示例中(即 E 没有子形状时),规则解释器将静默插入一个与规则本身具有相同名称的匿名叶形状。 应用上述 E 规则后的形状树如下所示:

应用 E 规则后的形状树
应用 E 规则后的形状树