com.badlogic.gdx.graphics.g3d.Attributes Maven / Gradle / Ivy
The newest version!
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.graphics.g3d;
import java.util.Comparator;
import java.util.Iterator;
import com.badlogic.gdx.utils.Array;
public class Attributes implements Iterable, Comparator, Comparable {
protected long mask;
protected final Array attributes = new Array();
protected boolean sorted = true;
/** Sort the attributes by their ID */
public final void sort () {
if (!sorted) {
attributes.sort(this);
sorted = true;
}
}
/** @return Bitwise mask of the ID's of all the containing attributes */
public final long getMask () {
return mask;
}
/** Example usage: ((BlendingAttribute)material.get(BlendingAttribute.ID)).sourceFunction;
* @return The attribute (which can safely be cast) if any, otherwise null */
public final Attribute get (final long type) {
if (has(type)) for (int i = 0; i < attributes.size; i++)
if (attributes.get(i).type == type) return attributes.get(i);
return null;
}
/** Example usage: ((BlendingAttribute)material.get(BlendingAttribute.ID)).sourceFunction;
* @return The attribute if any, otherwise null */
public final T get (Class clazz, final long type) {
return (T)get(type);
}
/** Get multiple attributes at once. Example: material.get(out, ColorAttribute.Diffuse | ColorAttribute.Specular |
* TextureAttribute.Diffuse); */
public final Array get (final Array out, final long type) {
for (int i = 0; i < attributes.size; i++)
if ((attributes.get(i).type & type) != 0) out.add(attributes.get(i));
return out;
}
/** Removes all attributes */
public void clear () {
mask = 0;
attributes.clear();
}
/** @return The amount of attributes this material contains. */
public int size () {
return attributes.size;
}
private final void enable (final long mask) {
this.mask |= mask;
}
private final void disable (final long mask) {
this.mask &= ~mask;
}
/** Add a attribute to this material. If the material already contains an attribute of the same type it is overwritten. */
public final void set (final Attribute attribute) {
final int idx = indexOf(attribute.type);
if (idx < 0) {
enable(attribute.type);
attributes.add(attribute);
sorted = false;
} else {
attributes.set(idx, attribute);
}
sort(); // FIXME: See #4186
}
/** Add multiple attributes to this material. If the material already contains an attribute of the same type it is
* overwritten. */
public final void set (final Attribute attribute1, final Attribute attribute2) {
set(attribute1);
set(attribute2);
}
/** Add multiple attributes to this material. If the material already contains an attribute of the same type it is
* overwritten. */
public final void set (final Attribute attribute1, final Attribute attribute2, final Attribute attribute3) {
set(attribute1);
set(attribute2);
set(attribute3);
}
/** Add multiple attributes to this material. If the material already contains an attribute of the same type it is
* overwritten. */
public final void set (final Attribute attribute1, final Attribute attribute2, final Attribute attribute3,
final Attribute attribute4) {
set(attribute1);
set(attribute2);
set(attribute3);
set(attribute4);
}
/** Add an array of attributes to this material. If the material already contains an attribute of the same type it is
* overwritten. */
public final void set (final Attribute... attributes) {
for (final Attribute attr : attributes)
set(attr);
}
/** Add an array of attributes to this material. If the material already contains an attribute of the same type it is
* overwritten. */
public final void set (final Iterable attributes) {
for (final Attribute attr : attributes)
set(attr);
}
/** Removes the attribute from the material, i.e.: material.remove(BlendingAttribute.ID); Can also be used to remove multiple
* attributes also, i.e. remove(AttributeA.ID | AttributeB.ID); */
public final void remove (final long mask) {
for (int i = attributes.size - 1; i >= 0; i--) {
final long type = attributes.get(i).type;
if ((mask & type) == type) {
attributes.removeIndex(i);
disable(type);
sorted = false;
}
}
sort(); // FIXME: See #4186
}
/** @return True if this collection has the specified attribute, i.e. attributes.has(ColorAttribute.Diffuse); Or when multiple
* attribute types are specified, true if this collection has all specified attributes, i.e. attributes.has(out,
* ColorAttribute.Diffuse | ColorAttribute.Specular | TextureAttribute.Diffuse); */
public final boolean has (final long type) {
return type != 0 && (this.mask & type) == type;
}
/** @return the index of the attribute with the specified type or negative if not available. */
protected int indexOf (final long type) {
if (has(type)) for (int i = 0; i < attributes.size; i++)
if (attributes.get(i).type == type) return i;
return -1;
}
/** Check if this collection has the same attributes as the other collection. If compareValues is true, it also compares the
* values of each attribute.
* @param compareValues True to compare attribute values, false to only compare attribute types
* @return True if this collection contains the same attributes (and optionally attribute values) as the other. */
public final boolean same (final Attributes other, boolean compareValues) {
if (other == this) return true;
if ((other == null) || (mask != other.mask)) return false;
if (!compareValues) return true;
sort();
other.sort();
for (int i = 0; i < attributes.size; i++)
if (!attributes.get(i).equals(other.attributes.get(i))) return false;
return true;
}
/** See {@link #same(Attributes, boolean)}
* @return True if this collection contains the same attributes (but not values) as the other. */
public final boolean same (final Attributes other) {
return same(other, false);
}
/** Used for sorting attributes by type (not by value) */
@Override
public final int compare (final Attribute arg0, final Attribute arg1) {
return (int)(arg0.type - arg1.type);
}
/** Used for iterating through the attributes */
@Override
public final Iterator iterator () {
return attributes.iterator();
}
/** @return A hash code based on only the attribute values, which might be different compared to {@link #hashCode()} because
* the latter might include other properties as well, i.e. the material id. */
public int attributesHash () {
sort();
final int n = attributes.size;
long result = 71 + mask;
int m = 1;
for (int i = 0; i < n; i++)
result += mask * attributes.get(i).hashCode() * (m = (m * 7) & 0xFFFF);
return (int)(result ^ (result >> 32));
}
@Override
public int hashCode () {
return attributesHash();
}
@Override
public boolean equals (Object other) {
if (!(other instanceof Attributes)) return false;
if (other == this) return true;
return same((Attributes)other, true);
}
@Override
public int compareTo (Attributes other) {
if (other == this) return 0;
if (mask != other.mask) return mask < other.mask ? -1 : 1;
sort();
other.sort();
for (int i = 0; i < attributes.size; i++) {
final int c = attributes.get(i).compareTo(other.attributes.get(i));
if (c != 0) return c < 0 ? -1 : (c > 0 ? 1 : 0);
}
return 0;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy