use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class MaterialContext method applyMaterial.
/**
* Applies material to a given geometry.
*
* @param geometry
* the geometry
* @param geometriesOMA
* the geometries OMA
* @param userDefinedUVCoordinates
* UV coords defined by user
* @param blenderContext
* the blender context
*/
public void applyMaterial(Geometry geometry, Long geometriesOMA, Map<String, List<Vector2f>> userDefinedUVCoordinates, BlenderContext blenderContext) {
Material material = null;
if (shadeless) {
material = new Material(blenderContext.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
if (!transparent) {
diffuseColor.a = 1;
}
material.setColor("Color", diffuseColor);
} else {
material = new Material(blenderContext.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
material.setBoolean("UseMaterialColors", Boolean.TRUE);
// setting the colors
if (!transparent) {
diffuseColor.a = 1;
}
material.setColor("Diffuse", diffuseColor);
material.setColor("Specular", specularColor);
material.setFloat("Shininess", shininess);
material.setColor("Ambient", new ColorRGBA(ambientFactor, ambientFactor, ambientFactor, 1f));
}
// applying textures
int textureIndex = 0;
if (loadedTextures != null && loadedTextures.size() > 0) {
if (loadedTextures.size() > TextureHelper.TEXCOORD_TYPES.length) {
LOGGER.log(Level.WARNING, "The blender file has defined more than {0} different textures. JME supports only {0} UV mappings.", TextureHelper.TEXCOORD_TYPES.length);
}
for (CombinedTexture combinedTexture : loadedTextures) {
if (textureIndex < TextureHelper.TEXCOORD_TYPES.length) {
String usedUserUVSet = combinedTexture.flatten(geometry, geometriesOMA, userDefinedUVCoordinates, blenderContext);
this.setTexture(material, combinedTexture.getMappingType(), combinedTexture.getResultTexture());
List<Vector2f> uvs = combinedTexture.getResultUVS();
if (uvs != null && uvs.size() > 0) {
VertexBuffer uvCoordsBuffer = new VertexBuffer(TextureHelper.TEXCOORD_TYPES[textureIndex++]);
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvs.toArray(new Vector2f[uvs.size()])));
geometry.getMesh().setBuffer(uvCoordsBuffer);
}
if (usedUserUVSet != null) {
userDefinedUVCoordinates = new HashMap<>(userDefinedUVCoordinates);
userDefinedUVCoordinates.remove(usedUserUVSet);
}
} else {
LOGGER.log(Level.WARNING, "The texture could not be applied because JME only supports up to {0} different UV's.", TextureHelper.TEXCOORD_TYPES.length);
}
}
}
if (userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
LOGGER.fine("Storing unused, user defined UV coordinates sets.");
if (userDefinedUVCoordinates.size() > TextureHelper.TEXCOORD_TYPES.length) {
LOGGER.log(Level.WARNING, "The blender file has defined more than {0} different UV coordinates for the mesh. JME supports only {0} UV coordinates buffers.", TextureHelper.TEXCOORD_TYPES.length);
}
for (Entry<String, List<Vector2f>> entry : userDefinedUVCoordinates.entrySet()) {
if (textureIndex < TextureHelper.TEXCOORD_TYPES.length) {
List<Vector2f> uvs = entry.getValue();
VertexBuffer uvCoordsBuffer = new VertexBuffer(TextureHelper.TEXCOORD_TYPES[textureIndex++]);
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvs.toArray(new Vector2f[uvs.size()])));
geometry.getMesh().setBuffer(uvCoordsBuffer);
} else {
LOGGER.log(Level.WARNING, "The user's UV set named: '{0}' could not be stored because JME only supports up to {1} different UV's.", new Object[] { entry.getKey(), TextureHelper.TEXCOORD_TYPES.length });
}
}
}
// applying additional data
material.setName(name);
if (vertexColor) {
material.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", true);
}
material.getAdditionalRenderState().setFaceCullMode(faceCullMode != null ? faceCullMode : blenderContext.getBlenderKey().getFaceCullMode());
if (transparent) {
material.setTransparent(true);
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
geometry.setQueueBucket(Bucket.Transparent);
}
geometry.setMaterial(material);
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class TestCustomAnim method simpleInitApp.
@Override
public void simpleInitApp() {
AmbientLight al = new AmbientLight();
rootNode.addLight(al);
DirectionalLight dl = new DirectionalLight();
dl.setDirection(Vector3f.UNIT_XYZ.negate());
rootNode.addLight(dl);
Box box = new Box(1, 1, 1);
VertexBuffer weightsHW = new VertexBuffer(Type.HWBoneWeight);
VertexBuffer indicesHW = new VertexBuffer(Type.HWBoneIndex);
indicesHW.setUsage(Usage.CpuOnly);
weightsHW.setUsage(Usage.CpuOnly);
box.setBuffer(weightsHW);
box.setBuffer(indicesHW);
// Setup bone weight buffer
FloatBuffer weights = FloatBuffer.allocate(box.getVertexCount() * 4);
VertexBuffer weightsBuf = new VertexBuffer(Type.BoneWeight);
weightsBuf.setupData(Usage.CpuOnly, 4, Format.Float, weights);
box.setBuffer(weightsBuf);
// Setup bone index buffer
ByteBuffer indices = ByteBuffer.allocate(box.getVertexCount() * 4);
VertexBuffer indicesBuf = new VertexBuffer(Type.BoneIndex);
indicesBuf.setupData(Usage.CpuOnly, 4, Format.UnsignedByte, indices);
box.setBuffer(indicesBuf);
// Create bind pose buffers
box.generateBindPose(true);
// Create skeleton
bone = new Bone("root");
bone.setBindTransforms(Vector3f.ZERO, Quaternion.IDENTITY, Vector3f.UNIT_XYZ);
bone.setUserControl(true);
skeleton = new Skeleton(new Bone[] { bone });
// Assign all verticies to bone 0 with weight 1
for (int i = 0; i < box.getVertexCount() * 4; i += 4) {
// assign vertex to bone index 0
indices.array()[i + 0] = 0;
indices.array()[i + 1] = 0;
indices.array()[i + 2] = 0;
indices.array()[i + 3] = 0;
// set weight to 1 only for first entry
weights.array()[i + 0] = 1;
weights.array()[i + 1] = 0;
weights.array()[i + 2] = 0;
weights.array()[i + 3] = 0;
}
// Maximum number of weights per bone is 1
box.setMaxNumWeights(1);
// Create model
Geometry geom = new Geometry("box", box);
geom.setMaterial(assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"));
Node model = new Node("model");
model.attachChild(geom);
// Create skeleton control
SkeletonControl skeletonControl = new SkeletonControl(skeleton);
model.addControl(skeletonControl);
rootNode.attachChild(model);
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class GeometryBatchFactory method mergeGeometries.
/**
* Merges all geometries in the collection into
* the output mesh. Creates a new material using the TextureAtlas.
*
* @param geometries
* @param outMesh
*/
public static void mergeGeometries(Collection<Geometry> geometries, Mesh outMesh) {
int[] compsForBuf = new int[VertexBuffer.Type.values().length];
Format[] formatForBuf = new Format[compsForBuf.length];
boolean[] normForBuf = new boolean[VertexBuffer.Type.values().length];
int totalVerts = 0;
int totalTris = 0;
int totalLodLevels = 0;
int maxWeights = -1;
Mode mode = null;
for (Geometry geom : geometries) {
totalVerts += geom.getVertexCount();
totalTris += geom.getTriangleCount();
totalLodLevels = Math.min(totalLodLevels, geom.getMesh().getNumLodLevels());
Mode listMode;
int components;
switch(geom.getMesh().getMode()) {
case Points:
listMode = Mode.Points;
components = 0;
break;
case LineLoop:
case LineStrip:
case Lines:
listMode = Mode.Lines;
components = 2;
break;
case TriangleFan:
case TriangleStrip:
case Triangles:
listMode = Mode.Triangles;
components = 3;
break;
default:
throw new UnsupportedOperationException();
}
for (VertexBuffer vb : geom.getMesh().getBufferList().getArray()) {
int currentCompsForBuf = compsForBuf[vb.getBufferType().ordinal()];
if (vb.getBufferType() != Type.Index && currentCompsForBuf != 0 && currentCompsForBuf != vb.getNumComponents()) {
throw new UnsupportedOperationException("The geometry " + geom + " buffer " + vb.getBufferType() + " has different number of components than the rest of the meshes " + "(this: " + vb.getNumComponents() + ", expected: " + currentCompsForBuf + ")");
}
compsForBuf[vb.getBufferType().ordinal()] = vb.getNumComponents();
formatForBuf[vb.getBufferType().ordinal()] = vb.getFormat();
normForBuf[vb.getBufferType().ordinal()] = vb.isNormalized();
}
maxWeights = Math.max(maxWeights, geom.getMesh().getMaxNumWeights());
if (mode != null && mode != listMode) {
throw new UnsupportedOperationException("Cannot combine different" + " primitive types: " + mode + " != " + listMode);
}
mode = listMode;
compsForBuf[Type.Index.ordinal()] = components;
}
outMesh.setMaxNumWeights(maxWeights);
outMesh.setMode(mode);
if (totalVerts >= 65536) {
// make sure we create an UnsignedInt buffer so
// we can fit all of the meshes
formatForBuf[Type.Index.ordinal()] = Format.UnsignedInt;
} else {
formatForBuf[Type.Index.ordinal()] = Format.UnsignedShort;
}
// generate output buffers based on retrieved info
for (int i = 0; i < compsForBuf.length; i++) {
if (compsForBuf[i] == 0) {
continue;
}
Buffer data;
if (i == Type.Index.ordinal()) {
data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris);
} else {
data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts);
}
VertexBuffer vb = new VertexBuffer(Type.values()[i]);
vb.setupData(Usage.Static, compsForBuf[i], formatForBuf[i], data);
vb.setNormalized(normForBuf[i]);
outMesh.setBuffer(vb);
}
int globalVertIndex = 0;
int globalTriIndex = 0;
for (Geometry geom : geometries) {
Mesh inMesh = geom.getMesh();
geom.computeWorldMatrix();
Matrix4f worldMatrix = geom.getWorldMatrix();
int geomVertCount = inMesh.getVertexCount();
int geomTriCount = inMesh.getTriangleCount();
for (int bufType = 0; bufType < compsForBuf.length; bufType++) {
VertexBuffer inBuf = inMesh.getBuffer(Type.values()[bufType]);
VertexBuffer outBuf = outMesh.getBuffer(Type.values()[bufType]);
if (inBuf == null || outBuf == null) {
continue;
}
if (Type.Index.ordinal() == bufType) {
int components = compsForBuf[bufType];
IndexBuffer inIdx = inMesh.getIndicesAsList();
IndexBuffer outIdx = outMesh.getIndexBuffer();
for (int tri = 0; tri < geomTriCount; tri++) {
for (int comp = 0; comp < components; comp++) {
int idx = inIdx.get(tri * components + comp) + globalVertIndex;
outIdx.put((globalTriIndex + tri) * components + comp, idx);
}
}
} else if (Type.Position.ordinal() == bufType) {
FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
doTransformVerts(inPos, globalVertIndex, outPos, worldMatrix);
} else if (Type.Normal.ordinal() == bufType) {
FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
doTransformNorms(inPos, globalVertIndex, outPos, worldMatrix);
} else if (Type.Tangent.ordinal() == bufType) {
FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
int components = inBuf.getNumComponents();
doTransformTangents(inPos, globalVertIndex, components, outPos, worldMatrix);
} else {
inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount);
}
}
globalVertIndex += geomVertCount;
globalTriIndex += geomTriCount;
}
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class GeometryBatchFactory method alignBuffers.
/**
* Will ensure that all the geometries' meshes of the n sub graph have the
* same types of buffers
* @param n the node to gather geometries from
* @param option the align options
* @see AlignOption
*
* Very experimental for now.
*/
public static void alignBuffers(Node n, AlignOption option) {
List<Geometry> geoms = new ArrayList<Geometry>();
gatherGeoms(n, geoms);
//gather buffer types
Map<VertexBuffer.Type, VertexBuffer> types = new EnumMap<VertexBuffer.Type, VertexBuffer>(VertexBuffer.Type.class);
Map<VertexBuffer.Type, Integer> typesCount = new EnumMap<VertexBuffer.Type, Integer>(VertexBuffer.Type.class);
for (Geometry geom : geoms) {
for (VertexBuffer buffer : geom.getMesh().getBufferList()) {
if (types.get(buffer.getBufferType()) == null) {
types.put(buffer.getBufferType(), buffer);
logger.log(Level.FINE, buffer.getBufferType().toString());
}
Integer count = typesCount.get(buffer.getBufferType());
if (count == null) {
count = 0;
}
count++;
typesCount.put(buffer.getBufferType(), count);
}
}
switch(option) {
case RemoveUnalignedBuffers:
for (Geometry geom : geoms) {
for (VertexBuffer buffer : geom.getMesh().getBufferList()) {
Integer count = typesCount.get(buffer.getBufferType());
if (count != null && count < geoms.size()) {
geom.getMesh().clearBuffer(buffer.getBufferType());
logger.log(Level.FINE, "removing {0} from {1}", new Object[] { buffer.getBufferType(), geom.getName() });
}
}
}
break;
case CreateMissingBuffers:
for (Geometry geom : geoms) {
for (VertexBuffer.Type type : types.keySet()) {
if (geom.getMesh().getBuffer(type) == null) {
VertexBuffer vb = new VertexBuffer(type);
Buffer b;
switch(type) {
case Index:
case BoneIndex:
case HWBoneIndex:
b = BufferUtils.createIntBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
break;
case InterleavedData:
b = BufferUtils.createByteBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
break;
default:
b = BufferUtils.createFloatBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents());
}
vb.setupData(types.get(type).getUsage(), types.get(type).getNumComponents(), types.get(type).getFormat(), b);
geom.getMesh().setBuffer(vb);
logger.log(Level.FINE, "geom {0} misses buffer {1}. Creating", new Object[] { geom.getName(), type });
}
}
}
break;
}
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class LodGenerator method makeLod.
private VertexBuffer makeLod(Mesh mesh) {
VertexBuffer indexBuffer = mesh.getBuffer(VertexBuffer.Type.Index);
boolean isShortBuffer = indexBuffer.getFormat() == VertexBuffer.Format.UnsignedShort;
// Create buffers.
VertexBuffer lodBuffer = new VertexBuffer(VertexBuffer.Type.Index);
int bufsize = indexCount == 0 ? 3 : indexCount;
if (isShortBuffer) {
lodBuffer.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.UnsignedShort, BufferUtils.createShortBuffer(bufsize));
} else {
lodBuffer.setupData(VertexBuffer.Usage.Static, 3, VertexBuffer.Format.UnsignedInt, BufferUtils.createIntBuffer(bufsize));
}
lodBuffer.getData().rewind();
//Check if we should fill it with a "dummy" triangle.
if (indexCount == 0) {
if (isShortBuffer) {
for (int m = 0; m < 3; m++) {
((ShortBuffer) lodBuffer.getData()).put((short) 0);
}
} else {
for (int m = 0; m < 3; m++) {
((IntBuffer) lodBuffer.getData()).put(0);
}
}
}
// Fill buffers.
Buffer buf = lodBuffer.getData();
buf.rewind();
for (Triangle triangle : triangleList) {
if (!triangle.isRemoved) {
// assert (indexCount != 0);
if (isShortBuffer) {
for (int m = 0; m < 3; m++) {
((ShortBuffer) buf).put((short) triangle.vertexId[m]);
}
} else {
for (int m = 0; m < 3; m++) {
((IntBuffer) buf).put(triangle.vertexId[m]);
}
}
}
}
buf.clear();
lodBuffer.updateData(buf);
return lodBuffer;
}
Aggregations