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

Фигуры

Опубликованно: 10.06.2018, 13:53
Последняя редакция, Andry: 17.11.2018 21:57

CSGShape можно построить из любой сетки. Никаких дополнительных примитивов, кроме тех, которые предоставляются базовыми службами jMonkey, не требуется. Однако при работе со смешиванием фигур с разными текстурами мне требовался более тонкий контроль над тем, как работают примитивные фигуры. И я хотел упростить построение XML. Итак, были созданы следующие.

CSGMesh

CSGMesh определяет общий подход дизайна к CSG фигурам примитивов, а также предоставляет общие сервисы для каждой конкретной фигуры. Примитив по существу строится из начала координат (0,0,0) с некоторым отклонением в зависимости от размера в сторону x, y и z. Фигура будет иметь грани, масштабирование текстур на которых можно индивидуально контролировать, и применять ваши пользовательские Материалы.

В частности, CSGMesh позволяет:

  • Примените различное масштабирование текстур к разным граням
  • Применяйте различные Материалы к разным граням
  • Генерировать различные уровней детализации на основе Коэффициента LOD
  • Производить TangentBinormal с информацией о освещении для Сетки после ее создания
  • Общая точка входа updateGeometry(), которая перестраивает фигуру, используя все текущие настройки

Точки java входа для сервисов выше:

CSGMesh  Описание
setFaceProperties( List pPropertyList )  Сохраните список свойств граней pPropertyList и примените их к соответствующим граням при запуске updateGeometry(). Каждый экземпляр CSGFaceProperties ссылается на выбранную грань (или грани) через битовую маску и имеет необязательное значение масштабирования текстуры (Vector2f) и/или настроенный Материал для применения к этой грани.
setLODFactors( float[ ] pLODFactors )  Сохраните набор процентных коэффициентов нагрузки, которые создают несколько VertexBuffer-ов при срабатывании updateGeometry(). Каждая конкретная фигура интерпретирует процент по-своему, решая, как наилучшим образом уменьшить количество индексов на нужную сумму. Но конечным результатом является вызов базового Mesh.setLodLevels(VertexBuffer[] pLevelsOfDetail).
setGenerateTangentBinormal( boolean pFlag )  Сохраните флаг, в true, что бы вызывалось TangentBinormalGenerator.generate(thisMesh) при вызове updateGeometry().
updateGeometry()  Создайте базовую Сетку (вершины, нормали, текстуры, индексы) из активных настроек конфигурации, а затем примените масштаб текстурирования и генерацию касательной бинормали по мере необходимости. Никакая реальная Сетка не доступна для этой фигур до тех пор, пока не будет вызвана функция updateGeometry(). Последним шагом обработки Savable.read(…) (…) для каждой CSG фигуры является вызов самой функции updateGeometry().

Грани выбираются целочисленной битовой маской, где:

0x01 - FRONT (Спереди) 
0x02 - BACK (Сзади) 
0x04 - LEFT (Слева) 
0x08 - RIGHT (Справа)
0x10 - TOP (Сверху)
0x20 - BOTTOM (Снизу)
0x40 - SIDES (Сторона)
0x80 - SURFACE (Поверхность)
и так же, можно логически комбинируя, применять этими же значениями те же свойства, к нескольким граням.

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

    <mesh class='net.wcomohundro.jme3.csg.shape.CSGSomeShape' 
            generateTangentBinormal='true' >
        <faceProperties>
            <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='FRONT_BACK' scaleX='1' scaleY='1.0'
                materialName='Textures/Rock/Rock1Rpt.xml' />
            <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='LEFT_RIGHT' scaleX='10' scaleY='1.0'/>
            <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='TOP_BOTTOM' scaleX='1' scaleY='10.0'/>
        </faceProperties>
        <lodFactors data='0.25 0.50'/>
    </mesh>

CSGBox

CSGBox создает базовую кирпичную фигуру с заданным x, y и z размером. Ключевое различие между CSGBox и стандартным jme3 Box(Куб) — это реализация граней (FRONT/BACK/TOP/BOTTOM/LEFT/RIGHT) и возможность применять различные свойства к разным сторонам.

Точки java входа для настройки конфигурации включают все, из CSGMesh и

CSGBox  Описание
setXExtent( float pExtent )
setYExtent( float pExtent )
setZExtent( float pExtent ) 
которые устанавливают размер куба в заданном направлении.

Обратите внимание, что размер применяется в плюс/минус от начала координат. То есть, конечная ширина/высота/глубина в два раза превышает значение размера.

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

    <mesh class='net.wcomohundro.jme3.csg.shape.CSGBox' 
            xExtent='5.0' yExtent='1.0' zExtent='1.0' >
        <faceProperties>
            <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='LEFT_RIGHT' scaleX='5.0' scaleY='1.0'/>
            <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='TOP_BOTTOM' scaleX='1' scaleY='5.0'/>
        </faceProperties>
    </mesh>

CSGBoxes

Куб что сверху, не имеет текстурного масштабирования, поэтому текстура растягивается чтобы покрыть растянутый размер. Куб что снизу имеет текстурное масштабирование, применяемое к четырем граням, рассчитанное для размера.

CSGAxialBox

CSGAxialBox — это второстепенный вариант CSGBox, где текстура применяется к граням LEFT/RIGHT/TOP/BOTTOM так же, как текстура применяется к круглым сторонам цилиндра. Это помогает при выравнивании текстур из смешанных примитивов.

Реализация XML импорта осуществляется в CSGAxialBox также как CSGBox. Просто замените одно на другое.

CSGAxial / CSGRadial

CSGAxial является расширением CSGMesh, которое реализует общий подход к проектированию примитивов CSG фигур, которые построены из серии срезов вдоль оси z. CSGRadial расширяет эту идею с каждого среза, определяемого вершинами, радиально распределенными вокруг его центра.
CSGRadialCapped — радиальная фигура с плоскими торцевыми крышками, такими как цилиндр или труба. Стандартные лицевые стороны FRONT/BACK/SIDES применяются ко всем закрытым радиальным элементам. Режим текстуры управляет тем, как текстура применяется к грани, где:

CAN  Представьте, что фигура наклона, чтобы сидеть на задней грани (like a soup can). Затем X перемещается по окружности, а Y увеличивается вверх на сколько можно.
ROLLER  Представьте, что фигура повернута так, что задняя сторона находится с лева, а передняя сторона с права. Тогда X линейно возрастает слева направо, а Y увеличивается вдоль окружности по мере продвижения вверх.

Точки java входа настраивающие радиальные фигуры:

CSGAxial/CSGRadial  Описание
setZExtent( float pZExtent )  Задать размер фигуры вдоль оси z
setAxisSamples( int pSampleCount )  Задать количество срезов для генерации вдоль оси z
setRadialSamples( int pSampleCount )  Задайте количество вершин для генерации вдоль внешней стороны каждого среза. Число три создает треугольную фигуру, число в четыре дает квадратную фигуру, более высокие числа производят круглые фигуры.
setFirstRadial( float pFirstRadial )  Задать угол (в радианах) первого радиального по оси x. Для круговых срезов это имеет минимальный эффект. Но если количество радиальных выборок невелико (3,4, …), то это определяет, где расположена первая вершина, в результате чего получается квадрат по сравнению с ромбом.
setRadius( float pRadius )  Радиус применяется к срезу, который определяет расстояние от вершины до центра.
setSliceScale( Vector2f pScaling )  x/y масштабирование к каждому отдельному срезу.
(общее масштабирование Геометрии, которая содержит эту фигуру, создает эллиптическую, а не круговую радиальность. Однако затем текстура, применяемая к каждому срезу, также масштабируется. Применение масштабирования к отдельному срезу сохраняет исходное отображение текстуры.)
setSliceRotation( float pTotalRotation )  Общая величина углового поворота (в радианах) от задней поверхности до передней поверхности с соответствующим фракционным количеством, применяемым к каждому срезу.
setClosed( boolean pIsClosed )  Если true, то концы фигуры закрыты. Если false, построена полая фигура без концов.
setInverted( boolean pIsInverted )  Если true, то фигура строится с её поверхностями, обращенными внутрь. Если false, то поверхности обращены наружу.

Точки java входа, настраивающие ограниченные радиальные фигуры:

 
setRadiusBack( float pRadius )  Радиус, применяемый к срезу задней поверхности, который определяет расстояние от вершины до центра. Когда радиус и задний радиус различаются, он будет скорректирован на каждом срезе, чтобы обеспечить плавное переход.
setTextureMode( CSGRadialCapped.TextureMode pTextureMode )  Задать, как текстура применяется к граням.

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

    <mesh class='net.wcomohundro.jme3.csg.shape.CSGSomeRadial' 
            zExtent='3.0' axisSamples='32' radialSamples='32' firstRadial='PI/4' 
            radius='1.1' scaleSliceX='2.0' scaleSliceY='2.0' twist='2PI' 
            radius2='1.7' textureMode='CAN' >
        ... other definitions from CSGMesh ...
    </mesh>

CSGCylinder

CSGCylinder создает базовую фигуру цилиндра, основываясь полностью на настройках CSGRadialCapped. Цилиндр может быть открыт или закрыт, а две торцевые крышки могут иметь разный радиус.

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

    <mesh class='net.wcomohundro.jme3.csg.shape.CSGCylinder' 
            zExtent='3.0' radius='1.1' />

CSGCylinders

Цилиндр слева применяет текстуру вокруг окружности, как CAN. В цилиндре справа применяется текстура, как ROLLER. Оба имеют текстуру «сторон», отмасштабированную, так чтобы было близко к масштабу на торцевых крышках.

CSGSphere

CSGSphere создает базовую фигуру сферу, основываясь на настройках CSGRadial. Сфера имеет только одну грань SURFACE (с интегральными концами) и применяется только один основной радиус. Сфера, отмеченная не закрытой, исключает срезы северного и южного полюсов, которые сходятся к одной точке, от чего крошечные отверстия появляются на концах.
Поскольку синус/косинус изменяются быстрее вблизи крайних углов, сфера может быть сгенерирован либо четными срезами (одинаковое расстояние на каждом шаге по оси z), либо для генерации большего количества срезов с меньшим шагом по оси z вблизи прямоугольных точек.
Режим текстуры управляет тем, как текстура применяется к полярным областям (последний участок, сгенерированный из общей центральной точки к срезу), где:

ZAXIS  Оберните текстуру радиально и вдоль оси z
PROJECTED  Оберните текстуру радиально, но сферически проецируйте вдоль оси z
POLAR  Примените текстуру к каждому полюсу. Устраняет полярное искажение, но зеркалит текстуру на экваторе

Точки java входа, настраивающие сферу:

setEvenSlices( boolean pFlag )  Если true, сгенерирует все шаги оси z равными. Если false, создаёт больше срезов рядом с крайними прямоугольными углами.
setTextureMode( CSGSphere.TextureMode pTextureMode )  задать режим текстуры применительно к полярным концам.

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

    <mesh class='net.wcomohundro.jme3.csg.shape.CSGSphere' 
            zExtent='3.0' radius='1.1' useEvenSlices='false' textureMode='ZAXIS' />

CSGSpheres

Сфера слева использует режим текстуры ZAXIS. Сфера в центре использует режим текстуры PROJECTED. Сфера справа использует режим текстуры POLAR.

CSGPipe

CSGPipe создает цилиндрическую форму, ось z которой соответствует заданному сплайну, а не прямой. Все настройки CSGRadialCapped применяются. Труба может быть открыта или закрыта, а две торцевые заглушки могут иметь разный радиус. Ключевым параметром является сплайн, используемый для генерации центральных точек оси z для каждого среза. Ожидается, что срез будет перпендикулярен его центральной точке на каждом интервале. Поскольку одна точка не имеет перпендикуляра, мы строим перпендикуляр к прямой между текущей центральной точкой и следующей. Это означает, что срезы концевой крышки могут быть очень чувствительны к структуре сплайна. Для обработки некоторых странностей различные настраиваемые параметры PipeEnd поддерживаются там, где:

STANDARD  Конечный срез генерируется «нормально», перпендикулярно последней точке кривой
PERPENDICULAR  Конечный срез генерируется перпендикулярно осям x / y / z
PERPENDICULAR45  Конечный срез генерируется перпендикулярно / 45 градусов по оси x / y / z
CROPPED  Конечные точки сплайна НЕ производят срез, они влияют только на последний срез

Еще одна странность строительных срезов вдоль сплайна, а не прямой, состоит в том, что из-за изгибов сплайна срезы могут сталкиваться друг с другом. Это приводит к очень смятой форме, если сплайн слишком сильно изгибается. Предоставляется возможность «сгладить» конечный результат. Он делает все возможное, чтобы устранить перекрытия среза.

Точки java входа, настраивающие канал:

setSlicePath( Spline pCurve )  Предоставьте сплайн jme3, который определяет положение каждой центральной точки среза.
setSmoothSurface( boolean pFlag )  Если true, сканируйте каждый фрагмент, ища столкновение со своим соседом. Если происходит перекрытие, примите меры, чтобы отрегулировать срез, чтобы устранить столкновение.
setPipeEnds( CSGPipe.PipeEnds pEnds )  Управляйте концами трубы.

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

    <mesh class='net.wcomohundro.jme3.csg.shape.CSGPipe' 
            pipeEnds='STANDARD' smoothSurface='false >
    	<slicePath class='net.wcomohundro.jme3.csg.shape.CSGSplineGenerator'  arc='PI'/>
    </mesh;>

CSGPipes

Слева направо: сплайн, тор, спираль.

CSGSplineGenerator (вспомогательный класс)

CSGSplineGenerator не является формой. Скорее, это вспомогательный класс, который может помочь в создании сплайна, используемого CSGPipe. Сплайн может быть определен:

  • Внешне определенный экземпляр сплайна
  • Явный набор точек
  • Набор контрольных точек, интерпретируемых на основе выбранного SplineType
  • Набор созданных точек вокруг дуги окружности с дополнительной регулировкой высоты, которая создает спираль, а не тор.

Точки java входа, настраивающие канал:

setSpline( Spline pSpline )  Используйте снайперский сплайн, как указано.
setPointList( List pPointList )  Используйте заданный набор точек, а не сплайн.
setArcRadius( float pRadius )  Создайте дугу заданного радиуса.
setArcRadians( float pRadians )  Создайте дугу данного угла (в радианах). Значение 2Pi будет генерировать полный тор. Значение, большее 2Pi, имеет смысл только для спирали.
setArcFirstRadial( float pRadial )  Создайте дугу, начинающуюся с точки с заданным углом (в радианах).
setHelixHeight( float pHeight )  Создайте спираль, которая охватывает заданную высоту.

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

    <slicePath class='net.wcomohundro.jme3.csg.shape.CSGSplineGenerator' 
    		radius='1.5' arc='PI' firstRadial='PI/4' helix='1.75' />
    		
    <slicePath class='net.wcomohundro.jme3.csg.shape.CSGSplineGenerator'  
    		type='Bezier' curveTension='0.5f' cycle='false'>
        <controlPoints>
            <com.jme3.math.Vector3f x='0.0' y='0.0' z='1.5'/>
            <com.jme3.math.Vector3f x='0.45' y='0.0' z='0.75'/>
            <com.jme3.math.Vector3f x='0.45' y='0.0' z='-0.75'/>
            <com.jme3.math.Vector3f x='00' y='0.0' z='-1.5'/>
        </controlPoints>
    </slicePath>

CSGTwisted

Образец тора, где каждый срез масштабируется в x / y для создания эллипса, срезы скручиваются спереди назад, а радиус начала отличается от радиуса конца.

CSGSurface
CSGSurface — это не сплошная, а двухмерная поверхность, используемая в качестве пола. Он похож на механизм jme3 Terrain, но не имеет поддержки LOD Terrain. Он работает, создавая сетку из стандартных данных jme3 HeightMap, с экстентами в X / Z, с высотой в Y.

Точки java входа, настраивающие поверхность:

setExtent( int pSizeOfSquareArea )  Ширина и глубина области (требуется 2 ** N + 1)
setHeightMap( float[] pHeightMap )  Высота каждой точки данных.
setScale( Vector3f pScale )  Шкала, применяемая ко всем точкам данных.

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

    <mesh class='net.wcomohundro.jme3.csg.shape.CSGSurface' extent='129'>
        <faceProperties>
            <net.wcomohundro.jme3.csg.shape.CSGFaceProperties 
					face='SURFACE' scaleX='1032' scaleY='1032'/>
        </faceProperties>
        <heightMap class='net.wcomohundro.jme3.csg.shape.CSGHeightMapGenerator'
            			type='HILL' size='129' scale='0.025' seed='12345' />
    </mesh>

CSGHeightMapGenerator (вспомогательный класс)

CSGHeightMapGenerator — это не форма. Скорее, это вспомогательный класс, который может помочь в построении данных HeightMap, используемых CSGSurface. Он включает поддержку основных классов jme3 в com.jme3.terrain.heightmap. В частности, типы:

DISPLACEMENT  uses MidpointDisplacementHeightMap
FAULT  uses FaultHeightMap
FLUID  uses FluidSimHeightMap
HILL  uses HillHeightMap
PARTICLE  uses ParticleDepositionHeightMap

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

    <heightMap class='net.wcomohundro.jme3.csg.shape.CSGSplineGenerator'  
    		type='HILL' size='257' iterations='100' seed='0'
    	... type specific parameters here, @see the code itself ...
    />

CSGFaceProperties (вспомогательный класс)

CSGFaceProperties — это не форма. Скорее, это вспомогательный класс, который может помочь в применении пользовательских материалов и масштабирования текстур для разных лиц в CSGMesh. В большинстве случаев CSGMesh играет роль стандартного jme3 Mesh. И в то время как Mesh понимает свое собственное сопоставление координат текстуры, он не знает о Материале, который применяется. Материал определяется и применяется геометрией, содержащей Mesh.

Но в рамках CSG становится очень удобно, если базовый CSGMesh может связать другой материал с разными лицами. Например, скажем, вы собираетесь определить комнату, вычитая меньшую внутреннюю коробку из немного большей внешней коробки. Если вы хотите, чтобы различные материалы применялись к полу по сравнению с потолком по сравнению с стенами, вы застряли, используя какое-либо соглашение о сопоставлении материалов или используя несколько примитивов для представления различных компонентов.

Поскольку CSGMesh понимает пользовательские материалы, сопоставленные с его различными лицами, и поскольку CSGGeonode понимает работу с несколькими Материалами, становится довольно легко определить конкретные для лица материалы непосредственно на CSGBox, и пусть стандартная обработка CSG применит соответствующий материал к соответствующим поверхностям.

Обратите внимание, что для основной обработки jme3 CSGBox — это просто Mesh. Нет основного процесса, чтобы заметить, что пользовательские материалы были определены на уровне Mesh. Но обработка CSGShape понимает несколько Материалов, применяемых к примитивам, и особенно ищет CSGMesh. Поэтому, если вы включаете CSGBox с пользовательскими Материалами с узлом Geometry jme3, эти Материалы игнорируются. Но если вы включите тот же CSGBox через CSGShape, добавленный в CSGGeonode, тогда используются пользовательские материалы.

CSGFaceProperties также используется для управления масштабированием текстуры и позиционированием, которое применяется к лицу. Это касается вопроса о ящике, продолговатом в z, но не в x и y. В этом случае передняя и задняя поверхности должны сохранять масштабирование текстуры единицы. Но левая / правая / верхняя / нижняя грани должны быть масштабированы соответствующим образом, чтобы предотвратить растяжение текстуры.

Помимо масштабирования текстуры, вы также можете управлять ее началом и интервалом. Обычно текстура проходит от 0.0 до 1.0 на лице. Масштабирование может учитывать лицо другого размера. Но при смешивании примитивов вы можете захотеть, чтобы текстура подкомпонента совпадала с текстурой более крупного компонента. Подумайте о создании кубиков с пипсами. Вы можете создать такой элемент, вычитая меньший цилиндр несколько раз из большего куба. Но если вы хотите, чтобы структура текстуры была непрерывной по пунктам, вам необходимо установить соответствующий источник текстуры для каждого цилиндра.

Помимо текстуры, вы можете управлять физическими свойствами на лице. На примере строительства комнаты вам могут понадобиться упругие стены, а также инертный пол. Это можно сделать, определив разные физические свойства для разных лиц.

В любом случае CSGFaceProperties применяется к лицу или граням, определяемому битовой маской всех вовлеченных лиц.

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

    <faceProperties>
	    <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='FRONT_BACK' scaleX='1' scaleY='1.5'
		        materialName='Textures/Rock/Rock1Rpt.xml'/>
        <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='LEFT_RIGHT' scaleX='2' scaleY='1.5'
		        materialName='Textures/BrickWall/BrickWallRpt.xml'/>
        <net.wcomohundro.jme3.csg.shape.CSGFaceProperties face='TOP_BOTTOM' scaleX='1' scaleY='2.0'/>
    </faceProperties>

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


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

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

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