Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Вклады
                jMonkey CSG - Конструктивная Сплошная Геометрия
                    Spatial-ы

Spatial-ы

Опубликованно: 06.06.2018, 21:09
Последняя редакция, Andry: 14.11.2018 17:05

Цель дизайна CSG заключается в том, чтобы сделать обработку логически максимально простой. В основе CSGSpatial лежит стандартный jme3 Spatial и он добавляется в вашу сцену, так же как и любой другой Spatial. Как к Spatial, к нему может также применяться стандартная Физика. Вы начинаете с создания одного из вариантов CSGSpatial (CSGGeometry, CSGGeonode).

Затем вы добавляете/вычитаете/пересекаете некоторый набор твердых тел к этому CSGSpatial. Каждое твердое тело представлено CSGShape, которое в главным образом представляет из себя CSG-обертку вокруг некоторой произвольной Сетки(Mesh). Эта Сетка может предоставлять собой jme3 примитив (Куб, Сферу, …), CSG примитив (CSGBox, CSGSphere, …) или что-то еще, что реализует Сетку.

После того, как твердые тела были смешаны в CSGSpatial, CSGSpatial должен быть «регенерирован». Это может быть сделано программным вызовом метода .regenerate( ), или это по сути, делается в конце обработки ввода Savable.

Последний шаг — добавить Spatial в вашу сцене, а также любую обработку control (например, физику), которая может потребоваться. На данный момент CSGSpatial не должен отличаться от любого другого jme3 Spatial, которые вы используете.

CSGSpatial

CSGSpatial — абстрактный интерфейс, определяющий стандартные CSG операции. Он реализует:

  • CSGGeometry — простая обёртка, поддерживающая единый общий Материал, применяемый ко всем частям
  • CSGGeonode — обертка, которая содержит набор Материалов, каждый из которых взят из различных фигур, смешанных с этим spatial
  • CSGLinkNode — вариант, полезный для обработки импорта Savable, который может обеспечить общую среду и/или Материал другим CSGSpatial-ам, созданным во время процесса импорта, и которые могут запустить загрузку таких игровых ресурсов. Однако он ничего не делает с CSGShape-ами.

Общими точками java входа для служб CSGSpatial являются:

CSGSpatial  Описание
addShape (CSGShape pShape)  Добавьте данную фигуру в процесс смешивания фигур с операцией Булево объединение(UNION).
subtractShape (CSGShape pShape)  Добавьте данную фигуру в процесс смешивания фигур с операцией Булева разность(DIFFERENCE).
intersectShape (CSGShape pShape)  Добавьте данную фигуру в процесс смешивания фигур с операцией Булево пересечение(INTERSECTION).
addShape (CSGShape pShape, CSGOperator pOperator)  Добавьте данную фигуру в процесс смешивания через явно заданную операцию.
removeAllShapes( )
removeShape( CSGShape pShape ) 
Удалить ранее добавленную фигуру из процесса смешивания.

Обратите внимание, что это НЕ вычитание. После удаления фигура уже не является какой либо частью смешанной фигуры.

regenerate( )
regenerate( CSGEnvironment pEnvironment ) 
Применит всю обработку активной фигуры и создаcn сетку. Если не будет явно указано CSGEnvironment, то будет использоваться стандартная среда системы.
Полученная в результате CSGShape возвращается .regenerate() и полученное смешение можно пере-смешивать что бы получать другой CSGSpatial.
isValid( )  После регенерации определяет, была ли действительно произведена Сетка или нет. Если значение недействительно, информация об ошибке доступна через .getError();
getShapeRegenerationNS( )  После регенерации возвращайте количество наносекунд в виде long, которое потребовалось для создания конечной Сетки.

Некоторые точки входа, реализованные в Геометрии, были добавлены в интерфейс CSGSpatial, так что Материалы и Уровень Детализации(LevelOfDetail) могут поддерживаться единообразно:

CSGSpatial  Описание
getMaterial()
setMaterial( Material pMaterial ) 
Аксессоры для контроля Материала, который применяется к этому Spatial.
getLodLevel()
setLodLevel( int pLODLevel ) 
Аксессоры для контроля Детализации(LevelOfDetail), который применяется к этому Spatial.

Реализация XML импорта выглядят примерно так:

<net.wcomohundro.jme3.csg.CSGLinkNode fname='CSGSamples'>
    <lights class='com.jme3.light.LightList'>
        <lights size='1'>
        	<com.jme3.light.AmbientLight name='ALight' enabled='true'>
        		<color class='com.jme3.math.ColorRGBA' r='1' g='1' b='1' a='1'/>
        	</com.jme3.light.AmbientLight>
        </lights>
    </lights>
    <children>
        <net.wcomohundro.jme3.csg.CSGGeonode name='BumpyCube'
        			materialName='Textures/Debug/Normals.xml'>
            <shapes>
                <net.wcomohundro.jme3.csg.CSGShape name='Box'>
                    <mesh class='net.wcomohundro.jme3.csg.shape.CSGBox' 
                    		xExtent='1.0' yExtent='1.0' zExtent='1.0'/>
                </net.wcomohundro.jme3.csg.CSGShape>
                
                <net.wcomohundro.jme3.csg.CSGShape name='Sphere' operator='UNION'>
                    <mesh class='net.wcomohundro.jme3.csg.shape.CSGSphere'
                    	 	axisSamples='64' radialSamples='64' radius='1.2'/>
                    <transform class='com.jme3.math.Transform'>
                        <translation class='com.jme3.math.Vector3f' x='0' y='0' z='0'/>
                    </transform>
                </net.wcomohundro.jme3.csg.CSGShape>
            </shapes>
        </net.wcomohundro.jme3.csg.CSGGeonode>
    </children>
</net.wcomohundro.jme3.csg.CSGLinkNode>

КБГФигура(CSGShape)

CSGShape предоставляет обертку, поддерживающую CSG, поверх jme3 Сетки. Программно тяжелая работа происходит в конструкторе, где фигура CSGShape создается с названием и Сеткой. Затем фигура добавляется в CSGSpatial вместе с оператором смешивания.

С точки зрения импорта XML оператор задаётся в самой CSGShape фигуре. См. пример выше …

Вы часто используете Transform при реализации CSGShape фигур для размещения, поворота и/или масштабирования элемента до его добавления в смешивание. Перемещение и масштабирование векторов довольно легко понять и настроить. Но XML вращение Кватерниона основано на внутренних значениях x/y/z/w, которые для человеческих глаз совершенно бессмысленны. Чтобы сделать XML более выразительным, вы можете использовать CSGTransform и CSGQuaternion. CSGTransform примет поворот реализованный как «com.jme3.math.Quaternion» или реализованный как «net.wcomohundro.jme3.math.CSGQuaternion». С помощью CSGQuaternion вы указываете тангаж(pitch)/рысканье(yaw)/крен(roll) в градусах радиана. Вы также можете использовать конструкцию PI и написать pitch=″PI/2″, чтобы выполнить тангаж фигуры на 90° относительно оси X.

Реализация XML импорта transform для CSGShape может выглядеть так:

        <csgtransform class='net.wcomohundro.jme3.math.CSGTransform'>
            <translation class='com.jme3.math.Vector3f' x='0' y='0' z='0'/>
            <scale class='com.jme3.math.Vector3f' x='0' y='0' z='0'/>
            <rot class='net.wcomohundro.jme3.math.CSGQuaternion' yawl='PI/2' pitch='PI/32' roll='PI'/>
        </csgtransform>

В реализации XML импорта вы можете найти более логичным, работать с группами под-элементов. Например, вы планируете создать коридор, который представляет собой растянутый куб, из которой вы вычитаете арку. Это можно сделать, начав с Куба, из которого вы вычитаете Куб с половинной высотой, чтобы получить нижнюю часть выреза арки, а затем вычитаете Цилиндр, чтобы вырезать верхнюю дугообразную часть полости. Но вы должны быть очень аккуратны, чтобы было соответствие размеров/масштаба/положения меньшего куба и цилиндра, чтобы все было выровнено как надо.

Наилучший подход — создать единую сущность, который представляет верхнюю дугу, смешанную с квадратным дном. Вы можете работать в простой блочной среде, чтобы все соответствующие текстуры были выровнены. Затем отмасштабируйте эту сущность как это нужно и вычтите его из большего куба. Вы можете это сделать с помощью определения <shapes> в CSGShape. Вместо того, чтобы предоставлять простую Сетку(Mesh), реализуйте набор CSGShape-ов (вместе с соответствующими им логическим операторами) в родительском CSGShape. Обработка внутренних под-элементов происходит до того, как будет всё смешано в родительской фигуре. Это позволяет вам применить преобразования на родительском уровне, чтобы получить желаемый масштаб и положение.

Реализация XML импорта для под-элементов CSGShape может выглядеть так:

    <net.wcomohundro.jme3.csg.CSGGeonode name='CSGGeometry' materialName='Textures/BrickWall/BrickWallRpt.xml' >
        <shapes>
            <net.wcomohundro.jme3.csg.CSGShape name='OuterBox'>
                <mesh class='net.wcomohundro.jme3.csg.shape.CSGBox' 
                    	... реализация внешнего куба здесь ...
            </net.wcomohundro.jme3.csg.CSGShape>
                
            <net.wcomohundro.jme3.csg.CSGShape name='InteriorArch' operator='DIFFERENCE' >
                <shapes>
                    <net.wcomohundro.jme3.csg.CSGShape name='SquareBottom' operator='UNION'>
                        <mesh class='net.wcomohundro.jme3.csg.shape.CSGAxialBox' 
                                    xExtent='0.5' yExtent='0.25' zExtent='0.5'>
                            <faceProperties>
                                <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='FRONT_BACK' scaleX='1' scaleY='0.5'/>
                                <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='LEFT_RIGHT' scaleX='1' scaleY='0.5'/>
                                <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='BOTTOM'
                                    materialName='Textures/Rock/Rock1NormalRpt.xml'/>
                            </faceProperties>
                        </mesh>
                        <transform class='com.jme3.math.Transform'>
                            <translation class='com.jme3.math.Vector3f' x='0' y='-0.25' z='0'/>
                        </transform>
                    </net.wcomohundro.jme3.csg.CSGShape>
                    <net.wcomohundro.jme3.csg.CSGShape name='ArchedRoof' operator='UNION'>
                        <mesh class='net.wcomohundro.jme3.csg.shape.CSGCylinder' 
                                axisSamples='34' closed='true' zExtent='0.5' 
                                radialSamples='32' radius='0.5' textureMode='ROLLER'>
                            <faceProperties>
                                <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='SIDES' scaleX='1' scaleY='PI'/>
                            </faceProperties>
                        </mesh>
                    </net.wcomohundro.jme3.csg.CSGShape>
                </shapes>
                ... теперь вы регулируете масштабирование текстуры в соответствии с желаемым размером выреза(cutout) ...
                <faceProperties>
                    <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='FRONT_BACK' scaleX='1.9' scaleY='1.9'/>
                    <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='LEFT_RIGHT' scaleX='19.9' scaleY='1.9'/>
                    <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='TOP_BOTTOM' scaleX='1.9' scaleY='19.9'/>
                    <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='SIDES' scaleX='19.9' scaleY='1.0'/>
                </faceProperties>
                <transform class='com.jme3.math.Transform'>
                    <scale class='com.jme3.math.Vector3f' x='1.90' y='1.90' z='19.9'/>
                </transform>
            </net.wcomohundro.jme3.csg.CSGShape> 
            ... другие операции смешивания здесь ...
        </shapes>
    </net.wcomohundro.jme3.csg.CSGGeonode>

CSGEnvironment

CSGEnviroment реализует общие параметры конфигурации, которые контролируют обработку CSG. Он позволяет устанавливать различные допустимые отклонения и параметры, которые влияют на внутреннюю работу генератора фигуры. Если вы не планируете очень глубоко разбираться в самом CSG-коде, настройка по умолчанию должна вам подойти.

По умолчанию используется обработку IOB (работающий с двойной точностью). Вы можете перевернуть всю систему, чтобы использовать обработку IOB, включив в свой код инициализации следующее (перед использованием любой службы CSG):

CSGEnvironment.resetEnvironment( new CSGEnvironmentBSP() );

CSGExternal

CSGExternal — это специальное расширение CSGShape, которое поддерживает Savable импорт, параметр который загружает свою Сетку с помощью функции AssetManager.loadModel(). Программного использования не существует, оно применяется только во время импорта.

Реализация XML импорта выглядят примерно так:

    <net.wcomohundro.jme3.csg.CSGExternal name='Teapot' operator='UNION' 
        model='Models/Teapot/Teapot.obj' />

Смотрите так же:


Переведено для jmonkeyengine.ru, оригинал
Автор перевода: Andry

Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.