Глядя на модель цилиндра, она имеет UV-карту от 0 до 1. Она используется для наложения текстуры на сетку.0,0 - левый нижний угол текстуры, а 1,1 - верхний правый.Конфигурация обтекания на пробоотборнике используется только тогда, когда координаты УФ на модели> 1,0.В этом случае он зажимается или повторяется в зависимости от настройки.Поскольку цилиндр уже ограничен до 0,1, текстура всегда растягивается.
Вы можете исправить это, либо смоделировать собственный цилиндр и установить координаты UV, как вам нужно, либо использовать собственный материал.чтобы манипулировать координатами UV перед выборкой.
Вы можете использовать Blender или Maya или другой инструмент трехмерного моделирования для создания модели.
Пользовательский материал специфичен для Sceneform, поэтому вот шаги:
- Создание фиктивной модели для использования при загрузке нестандартного материала
- Запись нестандартного материала, повторяющего текстуру
- Загрузка фиктивной модели во время выполнения и получение материала
- Установите параметры для пользовательского материала.
Создание фиктивной модели
Я использовал плоскую модель OBJ, которая была у меня рядом.Неважно, что это за модель, нам просто нужно загрузить материал.Создайте файл в app/sampledata/materials
с именем dummy.obj
o Plane
v 0.500000 0.500000 0.000000
v -0.500000 0.500000 0.000000
v 0.500000 -0.500000 0.000000
v -0.500000 -0.500000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vn 0.0000 0.0000 1.0000
usemtl None
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
Запись нестандартного материала
Справочник нестандартного материала описывает каждый изэлементы в repeating_texture.mat
:
// Sample material for repeating a texture.
//
// the repeating factor is given as repeat_x,
// repeat_y as a factor multipled by the UV
// coordinate.
material {
"name" : "RepeatingTexture",
parameters : [
{
type : sampler2d,
name : texture
},
{
type: float,
name:"repeat_x"
},
{
type: float,
name: "repeat_y"
}
],
requires : [
"position",
"uv0"
],
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
vec2 uv = getUV0();
uv.x = uv.x * materialParams.repeat_x;
uv.y = uv.y * materialParams.repeat_y;
material.baseColor = texture(materialParams_texture, uv).rgba;
}
}
Добавление модели и материала в сборку
Это добавляет шаг для компиляции модели и материала в .sfb
файл.В app/build.gradle
добавьте:
apply plugin: 'com.google.ar.sceneform.plugin'
sceneform.asset('sampledata/materials/dummy.obj',
"sampledata/materials/repeating_texture.mat",
'sampledata/materials/dummy.sfa',
'src/main/res/raw/material_holder')
Вам также необходимо добавить Sceneform в путь к классу buildscript на верхнем уровне build.gradle
:
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.google.ar.sceneform:plugin:1.5.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
Загрузить материал во время выполнения
В onCreate()
вызов:
ModelRenderable.builder (). SetSource (this, R.raw.material_holder) .build (). ThenAccept (modelRenderable -> repeatatingMaterial = modelRenderable.getMaterial ());
Сохраняет материал в поле элемента repeatingMaterial
.
Задайте параметры материала
Измените исходный код следующим образом:
private void addLineBetweenPoints(AnchorNode from, Vector3 to) {
// Compute a line's length
float lineLength = Vector3.subtract(from.getWorldPosition(), to).length();
// repeat the pattern every 10cm
float lengthCM = lineLength * 100;
repeatingMaterial.setFloat("repeat_x", lengthCM/10);
repeatingMaterial.setFloat("repeat_y", lengthCM/10);
// 3. make a model by the material
ModelRenderable model = ShapeFactory.makeCylinder(0.0025f, lineLength,
new Vector3(0f, lineLength / 2, 0f), repeatingMaterial);
model.setShadowReceiver(false);
model.setShadowCaster(false);
// make node
Node node = new Node();
node.setRenderable(model);
node.setParent(from);
// set rotation
final Vector3 difference = Vector3.subtract(from.getWorldPosition(), to);
final Vector3 directionFromTopToBottom = difference.normalized();
final Quaternion rotationFromAToB =
Quaternion.lookRotation(directionFromTopToBottom, Vector3.up());
node.setWorldRotation(Quaternion.multiply(rotationFromAToB,
Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), 90)));
}