/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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.android.scenegraph;
import java.lang.Math;
import java.util.ArrayList;
import com.android.scenegraph.SceneManager;
import android.renderscript.*;
import android.renderscript.Float3;
import android.renderscript.Matrix4f;
import android.util.Log;
/**
* @hide
*/
public class CompoundTransform extends Transform {
public static abstract class Component {
String mName;
CompoundTransform mParent;
int mParentIndex;
protected ScriptField_TransformComponent_s.Item mData;
Component(int type, String name) {
mData = new ScriptField_TransformComponent_s.Item();
mData.type = type;
mName = name;
}
void setNameAlloc() {
RenderScriptGL rs = SceneManager.getRS();
if (mData.name != null) {
return;
}
mData.name = SceneManager.getCachedAlloc(getName());
if (mData.name == null) {
mData.name = SceneManager.getStringAsAllocation(rs, getName());
SceneManager.cacheAlloc(getName(), mData.name);
}
}
ScriptField_TransformComponent_s.Item getRSData() {
setNameAlloc();
return mData;
}
protected void update() {
if (mParent != null) {
mParent.updateRSComponent(this);
}
}
public String getName() {
return mName;
}
}
public static class TranslateComponent extends Component {
public TranslateComponent(String name, Float3 translate) {
super(ScriptC_export.const_Transform_TRANSLATE, name);
setValue(translate);
}
public Float3 getValue() {
return new Float3(mData.value.x, mData.value.y, mData.value.z);
}
public void setValue(Float3 val) {
mData.value.x = val.x;
mData.value.y = val.y;
mData.value.z = val.z;
update();
}
}
public static class RotateComponent extends Component {
public RotateComponent(String name, Float3 axis, float angle) {
super(ScriptC_export.const_Transform_ROTATE, name);
setAxis(axis);
setAngle(angle);
}
public Float3 getAxis() {
return new Float3(mData.value.x, mData.value.y, mData.value.z);
}
public float getAngle() {
return mData.value.w;
}
public void setAxis(Float3 val) {
mData.value.x = val.x;
mData.value.y = val.y;
mData.value.z = val.z;
update();
}
public void setAngle(float val) {
mData.value.w = val;
update();
}
}
public static class ScaleComponent extends Component {
public ScaleComponent(String name, Float3 scale) {
super(ScriptC_export.const_Transform_SCALE, name);
setValue(scale);
}
public Float3 getValue() {
return new Float3(mData.value.x, mData.value.y, mData.value.z);
}
public void setValue(Float3 val) {
mData.value.x = val.x;
mData.value.y = val.y;
mData.value.z = val.z;
update();
}
}
ScriptField_TransformComponent_s mComponentField;
public ArrayList<Component> mTransformComponents;
public CompoundTransform() {
mTransformComponents = new ArrayList<Component>();
}
public TranslateComponent addTranslate(String name, Float3 translate) {
TranslateComponent c = new TranslateComponent(name, translate);
addComponent(c);
return c;
}
public RotateComponent addRotate(String name, Float3 axis, float angle) {
RotateComponent c = new RotateComponent(name, axis, angle);
addComponent(c);
return c;
}
public ScaleComponent addScale(String name, Float3 scale) {
ScaleComponent c = new ScaleComponent(name, scale);
addComponent(c);
return c;
}
public void addComponent(Component c) {
if (c.mParent != null) {
throw new IllegalArgumentException("Transform components may not be shared");
}
c.mParent = this;
c.mParentIndex = mTransformComponents.size();
mTransformComponents.add(c);
updateRSComponentAllocation();
}
public void setComponent(int index, Component c) {
if (c.mParent != null) {
throw new IllegalArgumentException("Transform components may not be shared");
}
if (index >= mTransformComponents.size()) {
throw new IllegalArgumentException("Invalid component index");
}
c.mParent = this;
c.mParentIndex = index;
mTransformComponents.set(index, c);
updateRSComponent(c);
}
void updateRSComponent(Component c) {
if (mField == null || mComponentField == null) {
return;
}
mComponentField.set(c.getRSData(), c.mParentIndex, true);
mField.set_isDirty(0, 1, true);
}
void updateRSComponentAllocation() {
if (mField == null) {
return;
}
initLocalData();
mField.set_components(0, mTransformData.components, false);
mField.set_isDirty(0, 1, true);
}
void initLocalData() {
RenderScriptGL rs = SceneManager.getRS();
int numComponenets = mTransformComponents.size();
if (numComponenets > 0) {
mComponentField = new ScriptField_TransformComponent_s(rs, numComponenets);
for (int i = 0; i < numComponenets; i ++) {
Component ith = mTransformComponents.get(i);
mComponentField.set(ith.getRSData(), i, false);
}
mComponentField.copyAll();
mTransformData.components = mComponentField.getAllocation();
}
}
}