Deprecated – Renderscript with Geomagnetic Field sensor

Gravity.java:
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);

mContext = Gravity.this;
 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
 mGeosensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

mView = new GravityView(this);
 setContentView(mView);

}

@Override
 protected void onResume() {
 super.onResume();
 mSensorManager.registerListener(this, mGeosensor, SensorManager.SENSOR_DELAY_NORMAL);
 mView.resume();
 }

@Override
 protected void onPause() {
 super.onPause();
 mSensorManager.unregisterListener(this);
 mView.pause();
 }

@Override
 public void onAccuracyChanged(Sensor sensor, int accuracy) {
 }

@Override
 public void onSensorChanged(SensorEvent event) {
 switch(event.sensor.getType()) {
 case Sensor.TYPE_MAGNETIC_FIELD:
 float lat = event.values[0];
 float lon = event.values[1];
 float alt = event.values[2];
 long timeMillis = event.timestamp;
 Log.i(TAG, String.format("Position: %f, %f, %f", lat, lon, alt));
 mView.setGeoPosition(lat, lon, alt, 1);
 break;
 }
 }

GravityRS.java:

public static final int PART_COUNT = 50000; // Count of particles

public GravityRS() {
 }

private Resources mRes;
 private RenderScriptGL mRS;
 private ScriptC_gravity mScript;

public void init(RenderScriptGL rs, Resources res, int width, int height) {
 mRS = rs;
 mRes = res;

ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
 pfb.setVaryingColor(true);
 rs.bindProgramFragment(pfb.create());

ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);

Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
 smb.addVertexAllocation(points.getAllocation());
 smb.addIndexSetType(Mesh.Primitive.POINT);
 Mesh sm = smb.create();

mScript = new ScriptC_gravity(mRS, mRes, R.raw.gravity);
 mScript.set_partMesh(sm);
 mScript.bind_point(points);
 mRS.bindRootScript(mScript);

mScript.invoke_initParticles(); // Initialize Particles
 }

public void newTouchPosition(float x, float y, float pressure, int id) {
 mScript.set_gTouchX(x);
 mScript.set_gTouchY(y);
 mScript.set_gTouchZ(pressure);
 }

GravityView.java:

public GravityView(Context context) {
 super(context);
 }

private RenderScriptGL mRS;
 private GravityRS mRender;

@Override
 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
 super.surfaceChanged(holder, format, w, h);
 if (mRS == null) {
 RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
 mRS = createRenderScriptGL(sc);
 mRS.setSurface(holder, w, h);

mRender = new GravityRS();
 mRender.init(mRS, getResources(), w, h);
 }
 }

@Override
 protected void onDetachedFromWindow() {
 if (mRS != null) {
 mRS = null;
 destroyRenderScriptGL();
 }
 }

public void setGeoPosition(float lat, float lon, float alt, int id) {
 mRender.newTouchPosition(lat, lon, alt, id);
 }

gravity.rs:

#pragma version(1)
#pragma rs java_package_name(edu.fsu.cs.mobile.geomagnetrs)
#pragma stateFragment(parent)

#include "rs_graphics.rsh"

static int newPart = 0;
static int initialized = 0;

float gTouchX = 50.f;
float gTouchY = 50.f;
float gTouchZ = 50.f;

typedef struct __attribute__((packed, aligned(4))) Point {
 float3 delta;
 float3 position;
 uchar4 color;
} Point_t;
Point_t *point;

rs_mesh partMesh;

/**
 * Initialize the particles
 */
void initParticles()
{
 int size = rsAllocationGetDimX(rsGetAllocation(point));
 float width = rsgGetWidth();
 float height = rsgGetHeight();
 uchar4 c = rsPackColorTo8888(0.0f, 0.9f, 0.9f);
 Point_t *p = point;
 for (int i = 0; i < size; i++) {
 p->position.x = rsRand(width);
 p->position.y = rsRand(height);
 p->position.z = 0;
 p->delta.x = 0;
 p->delta.y = 0;
 p->delta.z = 0;
 p->color = c;
 p++;
 }
 initialized = 1;
}

/**
 * root() is called every time a frame refresh occurs
 */
int root() {

 float width = rsgGetWidth();
 float height = rsgGetHeight();

 rsgClearColor(0.f, 0.f, 0.f, 1.f);

 int size = rsAllocationGetDimX(rsGetAllocation(point));
 Point_t *p = point;

for (int i = 0; i < size; i += 2) {
 float diff_x = gTouchX - p->position.x;
 float diff_y = gTouchY - p->position.y;
 float diff_z = gTouchZ - p->position.z;
 float acc = 50.f/(diff_x * diff_x + diff_y * diff_y + diff_z * diff_z);
// float acc = gTouchZ / 50.f;
 float acc_x = acc * diff_x;
 float acc_y = acc * diff_y;
 p->delta.x += acc_x;
 p->delta.y += acc_y;
 p->position.x += p->delta.x;
 p->position.y += p->delta.y;
 p->delta.x *= 0.96;
 p->delta.y *= 0.96;
 if (p->position.x > width) {
 p->position.x = 0;
 } else if (p->position.x < 0) {
// p->position.x = width;
 p->position.x = rsRand(width);
 }
 if (p->position.y > height) {
 p->position.y = 0;
 } else if (p->position.y < 0) {
// p->position.y = height;
 p->position.y = rsRand(height);
 }
 p++;
 }

 for (int i = 1; i < size; i += 2) {
 float diff_x = p->position.x - gTouchX;
 float diff_y = gTouchY - p->position.y;
 float diff_z = gTouchZ - p->position.z;
 float acc = 50.f/(diff_x * diff_x + diff_y * diff_y + diff_z * diff_z);
// float acc = gTouchZ / 50.f;
 float acc_x = acc * diff_x;
 float acc_y = acc * diff_y;
 p->delta.x += acc_x;
 p->delta.y += acc_y;
 p->position.x += p->delta.x;
 p->position.y += p->delta.y;
 p->delta.x *= 0.96;
 p->delta.y *= 0.96;
 if (p->position.x > width) {
 p->position.x = 0;
 } else if (p->position.x < 0) {
 p->position.x = width;
 }
 if (p->position.y > height) {
 p->position.y = 0;
 } else if (p->position.y < 0) {
 p->position.y = height;
 }
 p++;
 }

 rsgDrawMesh(partMesh);

 return 1;
}