public void setValue(VarType type, Object value) {
        assert !(value instanceof BindUnits);
        if (location == LOC_NOT_DEFINED) {
            return;
        }

        if (varType != null && varType != type) {
            throw new IllegalArgumentException("Expected a " + varType.name() + " value!");
        }

        if (value == null) {
            throw new IllegalArgumentException("for uniform " + name + ": value cannot be null");
        }

        setByCurrentMaterial = true;

        switch (type){
            case Matrix3:
                if (value.equals(this.value)) {
                    return;
                }
                Matrix3f m3 = (Matrix3f) value;
                if (multiData == null) {
                    multiData = BufferUtils.createFloatBuffer(9);
                }
                m3.fillFloatBuffer(multiData, true);
                multiData.clear();
                if (this.value == null) {
                    this.value = new Matrix3f(m3);
                } else {
                    ((Matrix3f)this.value).set(m3);
                }
                break;
            case Matrix4:
                if (value.equals(this.value)) {
                    return;
                }
                Matrix4f m4 = (Matrix4f) value;
                if (multiData == null) {
                    multiData = BufferUtils.createFloatBuffer(16);
                }
                m4.fillFloatBuffer(multiData, true);
                multiData.clear();
                if (this.value == null) {
                    this.value = new Matrix4f(m4);
                } else {
                    ((Matrix4f)this.value).copy(m4);
                }
                break;
            case IntArray:
                int[] ia = (int[]) value;
                if (this.value == null) {
                    this.value = BufferUtils.createIntBuffer(ia);
                } else {
                    this.value = BufferUtils.ensureLargeEnough((IntBuffer)this.value, ia.length);
                    ((IntBuffer)this.value).put(ia);
                }
                ((IntBuffer)this.value).clear();
                break;
            case FloatArray:
                float[] fa = (float[]) value;
                if (multiData == null) {
                    multiData = BufferUtils.createFloatBuffer(fa);
                } else {
                    multiData = BufferUtils.ensureLargeEnough(multiData, fa.length);
                    multiData.put(fa);
                }
                multiData.clear();
                break;
            case Vector2Array:
                Vector2f[] v2a = (Vector2f[]) value;
                if (multiData == null) {
                    multiData = BufferUtils.createFloatBuffer(v2a);
                } else {
                    multiData = BufferUtils.ensureLargeEnough(multiData, v2a.length * 2);
                    for (int i = 0; i < v2a.length; i++) {
                        BufferUtils.setInBuffer(v2a[i], multiData, i);
                    }
                }
                multiData.clear();
                break;
            case Vector3Array:
                Vector3f[] v3a = (Vector3f[]) value;
                if (multiData == null) {
                    multiData = BufferUtils.createFloatBuffer(v3a);
                } else {
                    multiData = BufferUtils.ensureLargeEnough(multiData, v3a.length * 3);
                    for (int i = 0; i < v3a.length; i++) {
                        BufferUtils.setInBuffer(v3a[i], multiData, i);
                    }
                }
                multiData.clear();
                break;
            case Vector4Array:
                Vector4f[] v4a = (Vector4f[]) value;
                if (multiData == null) {
                    multiData = BufferUtils.createFloatBuffer(v4a);
                } else {
                    multiData = BufferUtils.ensureLargeEnough(multiData, v4a.length * 4);
                    for (int i = 0; i < v4a.length; i++) {
                        BufferUtils.setInBuffer(v4a[i], multiData, i);
                    }
                }
                multiData.clear();
                break;
            case Matrix3Array:
                Matrix3f[] m3a = (Matrix3f[]) value;
                if (multiData == null) {
                    multiData = BufferUtils.createFloatBuffer(m3a.length * 9);
                } else {
                    multiData = BufferUtils.ensureLargeEnough(multiData, m3a.length * 9);
                }
                for (int i = 0; i < m3a.length; i++) {
                    m3a[i].fillFloatBuffer(multiData, true);
                }
                multiData.clear();
                break;
            case Matrix4Array:
                Matrix4f[] m4a = (Matrix4f[]) value;
                if (multiData == null) {
                    multiData = BufferUtils.createFloatBuffer(m4a.length * 16);
                } else {
                    multiData = BufferUtils.ensureLargeEnough(multiData, m4a.length * 16);
                }
                for (int i = 0; i < m4a.length; i++) {
                    m4a[i].fillFloatBuffer(multiData, true);
                }
                multiData.clear();
                break;
            case Vector2:
                if (value.equals(this.value)) {
                    return;
                }
                if (this.value == null) {
                    this.value = new Vector2f((Vector2f) value);
                } else {
                    ((Vector2f) this.value).set((Vector2f) value);
                }
                break;
            case Vector3:
                if (value.equals(this.value)) {
                    return;
                }
                if (this.value == null) {
                    this.value = new Vector3f((Vector3f) value);
                } else {
                    ((Vector3f) this.value).set((Vector3f) value);
                }
                break;
            case Vector4:
                if (value.equals(this.value)) {
                    return;
                }

                TempVars vars = TempVars.get();
                Vector4f vec4 = vars.vect4f1;
                //handle the null case
                if (this.value == null) {
                    try {
                        this.value = value.getClass().getDeclaredConstructor().newInstance();
                    } catch (InstantiationException | IllegalAccessException
                            | IllegalArgumentException | InvocationTargetException
                            | NoSuchMethodException | SecurityException e) {
                        throw new IllegalArgumentException("Cannot instantiate param of class " + value.getClass().getCanonicalName(), e);
                    }
                }
                //feed the pivot vec 4 with the correct value
                if (value instanceof ColorRGBA) {
                    ColorRGBA c = (ColorRGBA) value;
                    vec4.set(c.r, c.g, c.b, c.a);
                } else if (value instanceof Vector4f) {
                    vec4.set((Vector4f) value);
                } else {
                    Quaternion q = (Quaternion) value;
                    vec4.set(q.getX(), q.getY(), q.getZ(), q.getW());
                }

                //feed this.value with the collected values.
                if (this.value instanceof ColorRGBA) {
                    ((ColorRGBA) this.value).set(vec4.x, vec4.y, vec4.z, vec4.w);
                } else if (this.value instanceof Vector4f) {
                    ((Vector4f) this.value).set(vec4);
                } else {
                    ((Quaternion) this.value).set(vec4.x, vec4.y, vec4.z, vec4.w);
                }
                vars.release();
                break;
                // Only use check if equals optimization for primitive values
            case Int:
            case Float:
            case Boolean:
                if (value.equals(this.value)) {
                    return;
                }
                this.value = value;
                break;
            default:
                this.value = value;
                break;
        }

//        if (multiData != null) {
//            this.value = multiData;
//        }

        varType = type;
        updateNeeded = true;
    }
Used to track which uniforms to clear to avoid
values leaking from other materials that use that shader.
jme3-core/src/main/java/com/jme3/shader/Uniform.java