155a384c62528636190cfe0762228d4c2795c6883Romain Guy/* 255a384c62528636190cfe0762228d4c2795c6883Romain Guy * Copyright (C) 2009 The Android Open Source Project 355a384c62528636190cfe0762228d4c2795c6883Romain Guy * 455a384c62528636190cfe0762228d4c2795c6883Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 555a384c62528636190cfe0762228d4c2795c6883Romain Guy * you may not use this file except in compliance with the License. 655a384c62528636190cfe0762228d4c2795c6883Romain Guy * You may obtain a copy of the License at 755a384c62528636190cfe0762228d4c2795c6883Romain Guy * 855a384c62528636190cfe0762228d4c2795c6883Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 955a384c62528636190cfe0762228d4c2795c6883Romain Guy * 1055a384c62528636190cfe0762228d4c2795c6883Romain Guy * Unless required by applicable law or agreed to in writing, software 1155a384c62528636190cfe0762228d4c2795c6883Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 1255a384c62528636190cfe0762228d4c2795c6883Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1355a384c62528636190cfe0762228d4c2795c6883Romain Guy * See the License for the specific language governing permissions and 1455a384c62528636190cfe0762228d4c2795c6883Romain Guy * limitations under the License. 1555a384c62528636190cfe0762228d4c2795c6883Romain Guy */ 1655a384c62528636190cfe0762228d4c2795c6883Romain Guy 1755a384c62528636190cfe0762228d4c2795c6883Romain Guypackage com.android.wallpaper.grass; 1855a384c62528636190cfe0762228d4c2795c6883Romain Guy 1955a384c62528636190cfe0762228d4c2795c6883Romain Guyimport android.renderscript.Sampler; 2055a384c62528636190cfe0762228d4c2795c6883Romain Guyimport static android.renderscript.ProgramStore.DepthFunc.*; 2155a384c62528636190cfe0762228d4c2795c6883Romain Guyimport static android.renderscript.ProgramStore.BlendSrcFunc; 2255a384c62528636190cfe0762228d4c2795c6883Romain Guyimport static android.renderscript.ProgramStore.BlendDstFunc; 2376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchoukimport android.renderscript.*; 2455a384c62528636190cfe0762228d4c2795c6883Romain Guyimport static android.renderscript.Element.*; 2555a384c62528636190cfe0762228d4c2795c6883Romain Guyimport static android.util.MathUtils.*; 2676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchoukimport android.renderscript.Mesh.Primitive; 2755a384c62528636190cfe0762228d4c2795c6883Romain Guyimport static android.renderscript.Sampler.Value.*; 28a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.content.Context; 29a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.content.IntentFilter; 30a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.content.Intent; 31a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.content.BroadcastReceiver; 32a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.location.LocationManager; 33a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.location.LocationListener; 34a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.location.Location; 35a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.os.Bundle; 36a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport android.text.format.Time; 3755a384c62528636190cfe0762228d4c2795c6883Romain Guyimport com.android.wallpaper.R; 3844da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guyimport com.android.wallpaper.RenderScriptScene; 3955a384c62528636190cfe0762228d4c2795c6883Romain Guy 4055a384c62528636190cfe0762228d4c2795c6883Romain Guyimport java.util.TimeZone; 41a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guyimport java.util.Calendar; 4255a384c62528636190cfe0762228d4c2795c6883Romain Guy 4344da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guyclass GrassRS extends RenderScriptScene { 4441f1b533b84918dfce66c167ef879add467fefddRomain Guy @SuppressWarnings({"UnusedDeclaration"}) 45ab3bef5aa54658edf1bcda773f986d856d86ca43Romain Guy private static final String LOG_TAG = "Grass"; 4641f1b533b84918dfce66c167ef879add467fefddRomain Guy private static final boolean DEBUG = false; 4739761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams 48fee41f5a5d20c8520cf0fd22f6604f200c1600acRomain Guy private static final int LOCATION_UPDATE_MIN_TIME = DEBUG ? 5 * 60 * 1000 : 60 * 60 * 1000; // 1 hour 49fee41f5a5d20c8520cf0fd22f6604f200c1600acRomain Guy private static final int LOCATION_UPDATE_MIN_DISTANCE = DEBUG ? 10 : 150 * 1000; // 150 km 50a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private static final float TESSELATION = 0.5f; 5155a384c62528636190cfe0762228d4c2795c6883Romain Guy private static final int TEXTURES_COUNT = 5; 5255a384c62528636190cfe0762228d4c2795c6883Romain Guy private static final int BLADES_COUNT = 200; 532ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams 548aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams private ScriptField_Blade mBlades; 558aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams private ScriptField_Vertex mVertexBuffer; 5676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk private ProgramVertexFixedFunction.Constants mPvOrthoAlloc; 5755a384c62528636190cfe0762228d4c2795c6883Romain Guy 588aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams //private Allocation mBladesBuffer; 597a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams private Allocation mBladesIndicies; 60359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk private Mesh mBladesMesh; 61b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy 625f5044f59065ac339b175bb8a47ea6be861f925cStephen Hines private ScriptC_grass mScript; 632ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams 647a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams private int mVerticies; 657a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams private int mIndicies; 667a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams private int[] mBladeSizes; 6755a384c62528636190cfe0762228d4c2795c6883Romain Guy 68a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private final Context mContext; 69a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private final LocationManager mLocationManager; 70a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 71a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private LocationUpdater mLocationUpdater; 72a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private GrassRS.TimezoneTracker mTimezoneTracker; 73a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 74a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy GrassRS(Context context, int width, int height) { 7544da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy super(width, height); 76a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 77a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mContext = context; 78a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mLocationManager = (LocationManager) 79a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy context.getSystemService(Context.LOCATION_SERVICE); 80a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 81a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 82a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy @Override 83a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy public void start() { 84a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy super.start(); 85a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 86a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy if (mTimezoneTracker == null) { 87a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mTimezoneTracker = new TimezoneTracker(); 88a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy IntentFilter filter = new IntentFilter(); 89ab3bef5aa54658edf1bcda773f986d856d86ca43Romain Guy filter.addAction(Intent.ACTION_DATE_CHANGED); 90a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy filter.addAction(Intent.ACTION_TIME_CHANGED); 91a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 9239761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams 93a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mContext.registerReceiver(mTimezoneTracker, filter); 94a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 95a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 96a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy if (mLocationUpdater == null) { 97a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mLocationUpdater = new LocationUpdater(); 986bde8205bb9ae4afb3bb012f3bfb92019d6b1460Conley Owens try { 996bde8205bb9ae4afb3bb012f3bfb92019d6b1460Conley Owens mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1006bde8205bb9ae4afb3bb012f3bfb92019d6b1460Conley Owens LOCATION_UPDATE_MIN_TIME, LOCATION_UPDATE_MIN_DISTANCE, mLocationUpdater); 1016bde8205bb9ae4afb3bb012f3bfb92019d6b1460Conley Owens } catch (java.lang.IllegalArgumentException e) { 1026bde8205bb9ae4afb3bb012f3bfb92019d6b1460Conley Owens if (!e.getMessage().equals("provider=network")) { 1036bde8205bb9ae4afb3bb012f3bfb92019d6b1460Conley Owens throw e; 1046bde8205bb9ae4afb3bb012f3bfb92019d6b1460Conley Owens } 1056bde8205bb9ae4afb3bb012f3bfb92019d6b1460Conley Owens } 106a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 107a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 108a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy updateLocation(); 109a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 110a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 111a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy @Override 112a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy public void stop() { 113a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy super.stop(); 114a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 115a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy if (mTimezoneTracker != null) { 116a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mContext.unregisterReceiver(mTimezoneTracker); 117a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mTimezoneTracker = null; 118a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 11939761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams 120a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy if (mLocationUpdater != null) { 121a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mLocationManager.removeUpdates(mLocationUpdater); 122a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy mLocationUpdater = null; 123a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 1249e6f2347087ab40539b4c4b76f4b050f02184436Romain Guy } 1259e6f2347087ab40539b4c4b76f4b050f02184436Romain Guy 12644da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy @Override 12744da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy public void resize(int width, int height) { 12844da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy super.resize(width, height); 129575d514273135bb13ff662037b4ed4eb7c8aa985Jason Sams 1308aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gWidth(width); 1318aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gHeight(height); 132144361958bf67ff199ee65433af1a390dbd80fefJason Sams mScript.invoke_updateBlades(); 13376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk Matrix4f proj = new Matrix4f(); 13476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk proj.loadOrthoWindow(width, height); 13576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk mPvOrthoAlloc.setProjection(proj); 1369e6f2347087ab40539b4c4b76f4b050f02184436Romain Guy } 13744da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy 13844da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy @Override 13944da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy protected ScriptC createScript() { 14076469b31f1bda22057330a0146d9296df92b9094Jason Sams mScript = new ScriptC_grass(mRS, mResources, R.raw.grass); 1418aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams 1428aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams final boolean isPreview = isPreview(); 14355a384c62528636190cfe0762228d4c2795c6883Romain Guy createProgramVertex(); 14455a384c62528636190cfe0762228d4c2795c6883Romain Guy createProgramFragmentStore(); 14539761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams loadTextures(); 14655a384c62528636190cfe0762228d4c2795c6883Romain Guy createProgramFragment(); 147b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy createBlades(); 1488aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams 1498aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gBladesCount(BLADES_COUNT); 1508aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gIndexCount(mIndicies); 1518aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gWidth(mWidth); 1528aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gHeight(mHeight); 1538aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gXOffset(isPreview ? 0.5f : 0.f); 1548aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gIsPreview(isPreview ? 1 : 0); 1558aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gBladesMesh(mBladesMesh); 1568aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams 1578aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.setTimeZone(TimeZone.getDefault().getID()); 1588aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.bind_Blades(mBlades); 1598aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.bind_Verticies(mVertexBuffer); 1608aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams 1618aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams // set these to reasonable defaults. 1628aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gDawn(6.f / 24.f); 1638aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gDusk(18.f / 24.f); 1648aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gMorning(8.f / 24.f); // 2 hours for sunrise 1658aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gAfternoon(16.f / 24.f); // 2 hours for sunset 1668aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams 1678aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams return mScript; 168b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy } 169b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy 17044da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy @Override 17144da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) { 1728aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gXOffset(xOffset); 173b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy } 174b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy 175b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy private void createBlades() { 1767a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams mVerticies = 0; 1777a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams mIndicies = 0; 17855a384c62528636190cfe0762228d4c2795c6883Romain Guy 1798aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mBlades = new ScriptField_Blade(mRS, BLADES_COUNT); 180f0bb95619b01499e991bee297745cad31c20b28eRomain Guy 1817a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams mBladeSizes = new int[BLADES_COUNT]; 1822ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams for (int i = 0; i < BLADES_COUNT; i++) { 1838aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams ScriptField_Blade.Item item = new ScriptField_Blade.Item(); 1848aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams createBlade(item); 1858aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mBlades.set(item, i, false); 1868aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams 1878aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mIndicies += item.size * 2 * 3; 1888aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mVerticies += item.size + 2; 1898aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mBladeSizes[i] = item.size; 19055a384c62528636190cfe0762228d4c2795c6883Romain Guy } 1918aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mBlades.copyAll(); 192b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy 1937a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams createMesh(); 194b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy } 195b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy 1967a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams private void createMesh() { 1978aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mVertexBuffer = new ScriptField_Vertex(mRS, mVerticies * 2); 1988aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams 199359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS); 200359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk meshBuilder.addVertexAllocation(mVertexBuffer.getAllocation()); 201359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk 202359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk mBladesIndicies = Allocation.createSized(mRS, Element.U16(mRS), mIndicies); 20376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk meshBuilder.addIndexSetAllocation(mBladesIndicies, Primitive.TRIANGLE); 204b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy 205359f0324a761abae0977a35c0e072e409aecd544Alex Sakhartchouk mBladesMesh = meshBuilder.create(); 206b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy 2077a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams short[] idx = new short[mIndicies]; 2087a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams int idxIdx = 0; 2097a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams int vtxIdx = 0; 2107a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams for (int i = 0; i < mBladeSizes.length; i++) { 2117a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams for (int ct = 0; ct < mBladeSizes[i]; ct ++) { 2127a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams idx[idxIdx + 0] = (short)(vtxIdx + 0); 2137a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams idx[idxIdx + 1] = (short)(vtxIdx + 1); 2147a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams idx[idxIdx + 2] = (short)(vtxIdx + 2); 2157a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams idx[idxIdx + 3] = (short)(vtxIdx + 1); 2167a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams idx[idxIdx + 4] = (short)(vtxIdx + 3); 2177a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams idx[idxIdx + 5] = (short)(vtxIdx + 2); 2187a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams idxIdx += 6; 2197a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams vtxIdx += 2; 2207a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams } 2217a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams vtxIdx += 2; 222b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy } 2237a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams 22476469b31f1bda22057330a0146d9296df92b9094Jason Sams mBladesIndicies.copyFrom(idx); 22555a384c62528636190cfe0762228d4c2795c6883Romain Guy } 22655a384c62528636190cfe0762228d4c2795c6883Romain Guy 2278aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams private void createBlade(ScriptField_Blade.Item blades) { 228b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy final float size = random(4.0f) + 4.0f; 22944da17844aa73a047a1f1ff67b4794ea330be3b5Romain Guy final int xpos = random(-mWidth, mWidth); 230b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy 23155a384c62528636190cfe0762228d4c2795c6883Romain Guy //noinspection PointlessArithmeticExpression 2322ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.angle = 0.0f; 2332ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.size = (int)(size / TESSELATION); 2342ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.xPos = xpos; 2352ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.yPos = mHeight; 2362ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.offset = random(0.2f) - 0.1f; 2372ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.scale = 4.0f / (size / TESSELATION) + (random(0.6f) + 0.2f) * TESSELATION; 2382ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.lengthX = (random(4.5f) + 3.0f) * TESSELATION * size; 2392ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.lengthY = (random(5.5f) + 2.0f) * TESSELATION * size; 2402ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.hardness = (random(1.0f) + 0.2f) * TESSELATION; 2412ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.h = random(0.02f) + 0.2f; 2422ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.s = random(0.22f) + 0.78f; 2432ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.b = random(0.65f) + 0.35f; 2442ffa1cb7ec3fbfea042e45c2804d5dd4dd812b94Jason Sams blades.turbulencex = xpos * 0.006f; 24555a384c62528636190cfe0762228d4c2795c6883Romain Guy } 24655a384c62528636190cfe0762228d4c2795c6883Romain Guy 24755a384c62528636190cfe0762228d4c2795c6883Romain Guy private void loadTextures() { 2488aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gTNight(loadTexture(R.drawable.night)); 2498aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gTSunrise(loadTexture(R.drawable.sunrise)); 2508aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gTSky(loadTexture(R.drawable.sky)); 2518aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gTSunset(loadTexture(R.drawable.sunset)); 252b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams mScript.set_gTAa(generateTextureAlpha()); 25355a384c62528636190cfe0762228d4c2795c6883Romain Guy } 25455a384c62528636190cfe0762228d4c2795c6883Romain Guy 255b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams private Allocation generateTextureAlpha() { 256575d514273135bb13ff662037b4ed4eb7c8aa985Jason Sams final Type.Builder builder = new Type.Builder(mRS, A_8(mRS)); 257b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams builder.setX(4); 258b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams builder.setY(1); 25976469b31f1bda22057330a0146d9296df92b9094Jason Sams builder.setMipmaps(true); 260575d514273135bb13ff662037b4ed4eb7c8aa985Jason Sams 261ff72c0eec3b4b0400fc903bcc5ae78fa495a1678Jason Sams final Allocation allocation = Allocation.createTyped(mRS, builder.create(), 262ff72c0eec3b4b0400fc903bcc5ae78fa495a1678Jason Sams Allocation.USAGE_GRAPHICS_TEXTURE); 263b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams byte[] mip0 = new byte[] {0, -1, -1, 0}; 264b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams byte[] mip1 = new byte[] {64, 64}; 265b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams byte[] mip2 = new byte[] {0}; 2669c28ff884296f3c14e1bb1c2799c460f016e3f42Jason Sams 2679c28ff884296f3c14e1bb1c2799c460f016e3f42Jason Sams AllocationAdapter a = AllocationAdapter.create2D(mRS, allocation); 2689c28ff884296f3c14e1bb1c2799c460f016e3f42Jason Sams a.setLOD(0); 269b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams a.copyFrom(mip0); 2709c28ff884296f3c14e1bb1c2799c460f016e3f42Jason Sams a.setLOD(1); 271b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams a.copyFrom(mip1); 2729c28ff884296f3c14e1bb1c2799c460f016e3f42Jason Sams a.setLOD(2); 273b699d1f04a3452dd88ca68044ce93cc765369af4Jason Sams a.copyFrom(mip2); 2747a990688bb00e14ab9d3395539cd1971f09e93e5Jason Sams 27555a384c62528636190cfe0762228d4c2795c6883Romain Guy return allocation; 27655a384c62528636190cfe0762228d4c2795c6883Romain Guy } 27755a384c62528636190cfe0762228d4c2795c6883Romain Guy 2788aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams private Allocation loadTexture(int id) { 279bbcb547467bd09da372a15ac235e239c6557289bJason Sams return Allocation.createFromBitmapResource(mRS, mResources, id); 28055a384c62528636190cfe0762228d4c2795c6883Romain Guy } 28155a384c62528636190cfe0762228d4c2795c6883Romain Guy 28255a384c62528636190cfe0762228d4c2795c6883Romain Guy private void createProgramFragment() { 283b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy Sampler.Builder samplerBuilder = new Sampler.Builder(mRS); 28476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk samplerBuilder.setMinification(LINEAR_MIP_LINEAR); 28576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk samplerBuilder.setMagnification(LINEAR); 286b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy samplerBuilder.setWrapS(WRAP); 287b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy samplerBuilder.setWrapT(WRAP); 28839761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams Sampler sl = samplerBuilder.create(); 28939761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams 29076faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk samplerBuilder.setMinification(NEAREST); 29176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk samplerBuilder.setMagnification(NEAREST); 29239761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams Sampler sn = samplerBuilder.create(); 29339761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams 29476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS); 29576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, 29676faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk ProgramFragmentFixedFunction.Builder.Format.ALPHA, 0); 2975dde25d38dd72a709c7e7e6c9dd7975d39bd8b0aJason Sams builder.setVaryingColor(true); 2988aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams ProgramFragment pf = builder.create(); 2998aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gPFGrass(pf); 3008aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams pf.bindSampler(sl, 0); 30139761a986ce070f7761c6fcd2113b6e4cd18bb31Jason Sams 30276faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk builder = new ProgramFragmentFixedFunction.Builder(mRS); 30376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, 30476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk ProgramFragmentFixedFunction.Builder.Format.RGB, 0); 3058aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams pf = builder.create(); 3068aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gPFBackground(pf); 3078aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams pf.bindSampler(sn, 0); 30855a384c62528636190cfe0762228d4c2795c6883Romain Guy } 30955a384c62528636190cfe0762228d4c2795c6883Romain Guy 31055a384c62528636190cfe0762228d4c2795c6883Romain Guy private void createProgramFragmentStore() { 31176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk ProgramStore.Builder builder = new ProgramStore.Builder(mRS); 312b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy builder.setDepthFunc(ALWAYS); 313b7d225205d18b1f97a305ea07ef1de9ff8d86906Romain Guy builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); 31476faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk builder.setDitherEnabled(false); 31576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk builder.setDepthMaskEnabled(false); 3168aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gPSBackground(builder.create()); 31755a384c62528636190cfe0762228d4c2795c6883Romain Guy } 31855a384c62528636190cfe0762228d4c2795c6883Romain Guy 31955a384c62528636190cfe0762228d4c2795c6883Romain Guy private void createProgramVertex() { 32076faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk mPvOrthoAlloc = new ProgramVertexFixedFunction.Constants(mRS); 32176faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk Matrix4f proj = new Matrix4f(); 32276faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk proj.loadOrthoWindow(mWidth, mHeight); 32376faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk mPvOrthoAlloc.setProjection(proj); 32455a384c62528636190cfe0762228d4c2795c6883Romain Guy 32576faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); 3268aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams ProgramVertex pv = pvb.create(); 32776faca88c5c6c0e75cf05dc139f33c07df96366fAlex Sakhartchouk ((ProgramVertexFixedFunction)pv).bindConstants(mPvOrthoAlloc); 3288aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gPVBackground(pv); 32955a384c62528636190cfe0762228d4c2795c6883Romain Guy } 330a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 331a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private void updateLocation() { 332a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy updateLocation(mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)); 333a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 334a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 335a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private void updateLocation(Location location) { 3368aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams float dawn = 0.3f; 3378aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams float dusk = 0.75f; 3388aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams 339a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy if (location != null) { 340a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy final String timeZone = Time.getCurrentTimezone(); 341a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy final SunCalculator calculator = new SunCalculator(location, timeZone); 342a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy final Calendar now = Calendar.getInstance(); 343a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 344a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy final double sunrise = calculator.computeSunriseTime(SunCalculator.ZENITH_CIVIL, now); 3458aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams dawn = SunCalculator.timeToDayFraction(sunrise); 346a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 347a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy final double sunset = calculator.computeSunsetTime(SunCalculator.ZENITH_CIVIL, now); 3488aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams dusk = SunCalculator.timeToDayFraction(sunset); 349a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 350a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 3518aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gDawn(dawn); 3528aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gDusk(dusk); 3538aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gMorning(dawn + 1.0f / 12.0f); // 2 hours for sunrise 3548aeb9839d8b2ed85ab5a580d1b10554866add28aJason Sams mScript.set_gAfternoon(dusk - 1.0f / 12.0f); // 2 hours for sunset 355a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 356a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 357a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private class LocationUpdater implements LocationListener { 358a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy public void onLocationChanged(Location location) { 359a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy updateLocation(location); 360a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 361a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 362a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy public void onStatusChanged(String provider, int status, Bundle extras) { 363a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 364a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 365a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy public void onProviderEnabled(String provider) { 366a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 367a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 368a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy public void onProviderDisabled(String provider) { 369a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 370a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 371a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy 372a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy private class TimezoneTracker extends BroadcastReceiver { 373a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy public void onReceive(Context context, Intent intent) { 374a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy getScript().setTimeZone(Time.getCurrentTimezone()); 375a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy updateLocation(); 376a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 377a56ce01d5f2e831ad4a5ada54a3c10f8075e4921Romain Guy } 37855a384c62528636190cfe0762228d4c2795c6883Romain Guy} 379