/** * 描画用オブジェクト情報を作成する * * @param mqoMats MQOファイルから読み込んだマテリアル情報配列 * @param mqoObjs MQOファイルのオブジェクト情報 * @return 描画用オブジェクト情報 */ private GLObject makeObjs(GL10 gl, material mqoMats[], objects mqoObjs) { GLObject ret = null; ArrayList<GLMaterial> mats = new ArrayList<GLMaterial>(); GLMaterial mr; KGLPoint[] vn = null; vn = vNormal(mqoObjs); for (int m = 0; m < mqoMats.length; m++) { mr = makeMats(gl, mqoMats[m], m, mqoObjs, vn); if (mr != null) { mats.add(mr); } } if (mats.size() == 0) return null; ret = new GLObject(); ret.name = mqoObjs.name; ret.mat = mats.toArray(new GLMaterial[0]); ret.isVisible = (mqoObjs.data.visible != 0); return ret; }
String[] getPluginDirectories() { ArrayList<String> directories = new ArrayList<String>(); PackageManager pm = this.mAppContext.getPackageManager(); List<ResolveInfo> plugins = pm.queryIntentServices( new Intent(PLUGIN_ACTION), PackageManager.GET_SERVICES | PackageManager.GET_META_DATA); synchronized (mPackageInfoCache) { // clear the list of existing packageInfo objects mPackageInfoCache.clear(); for (ResolveInfo info : plugins) { // retrieve the plugin's service information ServiceInfo serviceInfo = info.serviceInfo; if (serviceInfo == null) { Log.w(LOGTAG, "Ignore bad plugin"); continue; } Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName); // retrieve information from the plugin's manifest PackageInfo pkgInfo; try { pkgInfo = pm.getPackageInfo( serviceInfo.packageName, PackageManager.GET_PERMISSIONS | PackageManager.GET_SIGNATURES); } catch (Exception e) { Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName); continue; } if (pkgInfo == null) { Log.w( LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Could not load package information."); continue; } /* * find the location of the plugin's shared library. The default * is to assume the app is either a user installed app or an * updated system app. In both of these cases the library is * stored in the app's data directory. */ String directory = pkgInfo.applicationInfo.dataDir + "/lib"; final int appFlags = pkgInfo.applicationInfo.flags; final int updatedSystemFlags = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; // preloaded system app with no user updates if ((appFlags & updatedSystemFlags) == ApplicationInfo.FLAG_SYSTEM) { directory = PLUGIN_SYSTEM_LIB + pkgInfo.packageName; } // check if the plugin has the required permissions String permissions[] = pkgInfo.requestedPermissions; if (permissions == null) { Log.w( LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Does not have required permission."); continue; } boolean permissionOk = false; for (String permit : permissions) { if (PLUGIN_PERMISSION.equals(permit)) { permissionOk = true; break; } } if (!permissionOk) { Log.w( LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Does not have required permission (2)."); continue; } // check to ensure the plugin is properly signed Signature signatures[] = pkgInfo.signatures; if (signatures == null) { Log.w(LOGTAG, "Loading plugin: " + serviceInfo.packageName + ". Not signed."); continue; } // determine the type of plugin from the manifest if (serviceInfo.metaData == null) { Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no type defined"); continue; } String pluginType = serviceInfo.metaData.getString(PLUGIN_TYPE); if (!TYPE_NATIVE.equals(pluginType)) { Log.e(LOGTAG, "Unrecognized plugin type: " + pluginType); continue; } try { Class<?> cls = getPluginClass(serviceInfo.packageName, serviceInfo.name); // TODO implement any requirements of the plugin class here! boolean classFound = true; if (!classFound) { Log.e( LOGTAG, "The plugin's class' " + serviceInfo.name + "' does not extend the appropriate class."); continue; } } catch (NameNotFoundException e) { Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName); continue; } catch (ClassNotFoundException e) { Log.e(LOGTAG, "Can't find plugin's class: " + serviceInfo.name); continue; } // if all checks have passed then make the plugin available mPackageInfoCache.add(pkgInfo); directories.add(directory); } } return directories.toArray(new String[directories.size()]); }
/** * 描画用マテリアル情報をMQOデータから作成 * * @param mqomat MQOファイルから読み込んだマテリアル情報 * @param i_mqomat MQOファイルのマテリアル番号 * @param mqoObjs MQOファイルのオブジェクト情報 * @param vn 頂点法線配列 * @return 描画用マテリアル情報 */ private GLMaterial makeMats( GL10 gl, material mqomat, int i_mqomat, objects mqoObjs, KGLPoint[] vn) { GLMaterial ret = new GLMaterial(); ArrayList<KGLPoint> apv = new ArrayList<KGLPoint>(); ArrayList<KGLPoint> apn = new ArrayList<KGLPoint>(); ArrayList<KGLPoint> apuv = new ArrayList<KGLPoint>(); ArrayList<KGLPoint> apc = new ArrayList<KGLPoint>(); KGLPoint wpoint = null; boolean uvValid = false; boolean colValid = false; KGLPoint fn; float s; for (int f = 0; f < mqoObjs.face.length; f++) { if (mqoObjs.face[f].M == null) { continue; } if (mqoObjs.face[f].M != i_mqomat) continue; fn = calcNormal( mqoObjs.vertex, mqoObjs.face[f].V[0], mqoObjs.face[f].V[1], mqoObjs.face[f].V[2]); for (int v = 0; v < 3; v++) { apv.add(mqoObjs.vertex[mqoObjs.face[f].V[v]]); // apv.add(new KGLPoint(mqoObjs.vertex[mqoObjs.face[f].V[v]])) ; s = (float) Math.acos( fn.X() * vn[mqoObjs.face[f].V[v]].X() + fn.Y() * vn[mqoObjs.face[f].V[v]].Y() + fn.Z() * vn[mqoObjs.face[f].V[v]].Z()); if (mqoObjs.data.facet < s) { apn.add(fn); } else { apn.add(vn[mqoObjs.face[f].V[v]]); } wpoint = new KGLPoint(2); if (mqoObjs.face[f].UV == null) { wpoint.set_UV(0, 0); } else { wpoint.set_UV(mqoObjs.face[f].UV[v * 2 + 0], mqoObjs.face[f].UV[v * 2 + 1]); uvValid = true; } apuv.add(wpoint); wpoint = new KGLPoint(4); if (mqoObjs.face[f].COL == null) { if (mqomat.data.col == null) { wpoint.set_COLOR(1.0f, 1.0f, 1.0f, 1.0f); } else { wpoint.set_COLOR( mqomat.data.col[0], mqomat.data.col[1], mqomat.data.col[2], mqomat.data.col[3]); } } else { wpoint.set_COLOR( mqoObjs.face[f].COL[v * 4 + 0], mqoObjs.face[f].COL[v * 4 + 1], mqoObjs.face[f].COL[v * 4 + 2], mqoObjs.face[f].COL[v * 4 + 3]); colValid = true; } apc.add(wpoint); } } ret.texID = texPool.getGLTexture(gl, mqomat.data.tex, mqomat.data.aplane, false); // @@@ reload 用 if (ret.texID != 0) { ret.texName = mqomat.data.tex; ret.alphaTexName = mqomat.data.aplane; } else { ret.texName = null; ret.alphaTexName = null; } if (apv.size() == 0) return null; uvValid &= (ret.texID != 0); ret.name = mqomat.name; // uvValid = false ; KGLPoint[] wfv = null; KGLPoint[] wfn = null; KGLPoint[] wft = null; KGLPoint[] wfc = null; wfv = apv.toArray(new KGLPoint[0]); wfn = apn.toArray(new KGLPoint[0]); wft = apuv.toArray(new KGLPoint[0]); wfc = apc.toArray(new KGLPoint[0]); ret.vertex_num = wfv.length; // @@@ interleaveFormat は無いので分ける ret.uvValid = uvValid; ret.colValid = colValid; ret.vertexBuffer = ByteBuffer.allocateDirect(ret.vertex_num * 3 * 4); ret.vertexBuffer.order(ByteOrder.nativeOrder()); ret.vertexBuffer.position(0); ret.normalBuffer = ByteBuffer.allocateDirect(ret.vertex_num * 3 * 4); ret.normalBuffer.order(ByteOrder.nativeOrder()); ret.normalBuffer.position(0); if (uvValid) { ret.uvBuffer = ByteBuffer.allocateDirect(ret.vertex_num * 2 * 4); ret.uvBuffer.order(ByteOrder.nativeOrder()); ret.uvBuffer.position(0); } if (colValid) { ret.colBuffer = ByteBuffer.allocateDirect(ret.vertex_num * 4 * 4); ret.colBuffer.order(ByteOrder.nativeOrder()); ret.colBuffer.position(0); } // Log.i("KGLMetaseq", "vertex_num: "+ ret.vertex_num); for (int v = 0; v < ret.vertex_num; v++) { ret.vertexBuffer.putFloat(wfv[v].X()); ret.vertexBuffer.putFloat(wfv[v].Y()); ret.vertexBuffer.putFloat(wfv[v].Z()); ret.normalBuffer.putFloat(wfn[v].X()); ret.normalBuffer.putFloat(wfn[v].Y()); ret.normalBuffer.putFloat(wfn[v].Z()); if (uvValid) { ret.uvBuffer.putFloat(wft[v].U()); ret.uvBuffer.putFloat(wft[v].V()); } if (colValid) { ret.colBuffer.putFloat(wfc[v].R()); ret.colBuffer.putFloat(wfc[v].G()); ret.colBuffer.putFloat(wfc[v].B()); ret.colBuffer.putFloat(wfc[v].A()); } } if (mqomat.data.col != null) { ret.color = new float[mqomat.data.col.length]; for (int c = 0; c < mqomat.data.col.length; c++) { ret.color[c] = mqomat.data.col[c]; } if (mqomat.data.dif != null) { ret.dif = new float[mqomat.data.col.length]; for (int c = 0; c < mqomat.data.col.length; c++) { ret.dif[c] = mqomat.data.dif * mqomat.data.col[c]; } // KEICHECK difでアルファ値を1未満にすると透明度が変化する? ret.dif[3] = mqomat.data.col[3]; } if (mqomat.data.amb != null) { ret.amb = new float[mqomat.data.col.length]; for (int c = 0; c < mqomat.data.col.length; c++) { ret.amb[c] = mqomat.data.amb * mqomat.data.col[c]; } } if (mqomat.data.emi != null) { ret.emi = new float[mqomat.data.col.length]; for (int c = 0; c < mqomat.data.col.length; c++) { ret.emi[c] = mqomat.data.emi * mqomat.data.col[c]; } } if (mqomat.data.spc != null) { ret.spc = new float[mqomat.data.col.length]; for (int c = 0; c < mqomat.data.col.length; c++) { ret.spc[c] = mqomat.data.spc * mqomat.data.col[c]; } } } if (mqomat.data.pow != null) { ret.power = new float[1]; ret.power[0] = mqomat.data.pow; } ret.shadeMode_IsSmooth = true; // defaultはtrue if (mqoObjs.data.shading == 0) ret.shadeMode_IsSmooth = false; return ret; }
/** * faceチャンクの読み込み * * @param br 読み込みストリーム * @return 面配列 * @throws Exception */ private Face[] readFace(multiInput br) throws Exception { ArrayList<Face> qf; String line = null; String[] s; Integer Mn; Face[] wface = null; int p; int pe; qf = new ArrayList<Face>(); try { while ((line = br.readLine()) != null) { if (line.length() <= 0) continue; line = line.trim(); if (line.equals("}")) break; wface = null; Mn = null; p = line.indexOf("M("); if (p != -1) { pe = line.indexOf(")", p); Mn = Integer.parseInt(line.substring(p + 2, pe)); } p = line.indexOf("V("); if (p == -1) continue; pe = line.indexOf(")", p); s = line.substring(p + 2, pe).split(" "); if (s.length == 3) { wface = new Face[1]; wface[0] = new Face(); wface[0].V = new Integer[3]; wface[0].V[0] = Integer.parseInt(s[0]); wface[0].V[1] = Integer.parseInt(s[1]); wface[0].V[2] = Integer.parseInt(s[2]); wface[0].M = Mn; p = line.indexOf("UV("); if (p != -1) { pe = line.indexOf(")", p); s = line.substring(p + 3, pe).split(" "); if (s.length != 2 * 3) throw new Exception("UVの数が不正"); wface[0].UV = new Float[2 * 3]; for (int i = 0; i < s.length; i++) { wface[0].UV[i] = Float.parseFloat(s[i]); } } p = line.indexOf("COL("); if (p != -1) { pe = line.indexOf(")", p); s = line.substring(p + 4, pe).split(" "); if (s.length != 3) throw new Exception("COLの数が不正"); wface[0].COL = new Float[4 * 3]; long wl; float wf; for (int i = 0; i < s.length; i++) { wl = Long.parseLong(s[i]); wf = (wl >>> 0) & 0x000000ff; wface[0].COL[i * 4 + 0] = wf / 255f; wf = (wl >>> 8) & 0x000000ff; wface[0].COL[i * 4 + 1] = wf / 255f; wf = (wl >>> 16) & 0x000000ff; wface[0].COL[i * 4 + 2] = wf / 255f; wf = (wl >>> 24) & 0x000000ff; wface[0].COL[i * 4 + 3] = wf / 255f; } } } // 頂点配列はすべて三角にするので、四角は三角x2に分割 // 0 3 0 0 3 // □ → △ ▽ // 1 2 1 2 2 if (s.length == 4) { wface = new Face[2]; wface[0] = new Face(); wface[1] = new Face(); wface[0].V = new Integer[3]; wface[0].V[0] = Integer.parseInt(s[0]); wface[0].V[1] = Integer.parseInt(s[1]); wface[0].V[2] = Integer.parseInt(s[2]); wface[0].M = Mn; wface[1].V = new Integer[3]; wface[1].V[0] = Integer.parseInt(s[0]); wface[1].V[1] = Integer.parseInt(s[2]); wface[1].V[2] = Integer.parseInt(s[3]); wface[1].M = Mn; p = line.indexOf("UV("); if (p != -1) { int uv_p; pe = line.indexOf(")", p); s = line.substring(p + 3, pe).split(" "); if (s.length != 2 * 4) throw new Exception("UVの数が不正"); wface[0].UV = new Float[2 * 3]; wface[1].UV = new Float[2 * 3]; for (int i = 0; i < 2; i++) { uv_p = 0; for (int j = 0; j < 4; j++) { if (i == 0 && j == 3) continue; if (i == 1 && j == 1) continue; wface[i].UV[uv_p++] = Float.parseFloat(s[j * 2 + 0]); wface[i].UV[uv_p++] = Float.parseFloat(s[j * 2 + 1]); } } } p = line.indexOf("COL("); if (p != -1) { pe = line.indexOf(")", p); s = line.substring(p + 4, pe).split(" "); if (s.length != 4) throw new Exception("COLの数が不正"); wface[0].COL = new Float[4 * 3]; wface[1].COL = new Float[4 * 3]; long wl; float wf; int col_p; for (int i = 0; i < 2; i++) { col_p = 0; for (int j = 0; j < s.length; j++) { if (i == 0 && j == 3) continue; if (i == 1 && j == 1) continue; wl = Long.parseLong(s[j]); wf = (wl >>> 0) & 0x000000ff; wface[i].COL[col_p * 4 + 0] = wf / 255f; wf = (wl >>> 8) & 0x000000ff; wface[i].COL[col_p * 4 + 1] = wf / 255f; wf = (wl >>> 16) & 0x000000ff; wface[i].COL[col_p * 4 + 2] = wf / 255f; wf = (wl >>> 24) & 0x000000ff; wface[i].COL[col_p * 4 + 3] = wf / 255f; col_p++; } } } } if (wface != null) { for (int i = 0; i < wface.length; i++) { qf.add(wface[i]); } } } } catch (Exception e) { Log.e("KGLMetaseq", "MQOファイル フォーマットエラー(Object>face)" + e.getMessage() + "[" + line + "]"); throw e; } if (qf.size() == 0) return null; return qf.toArray(new Face[0]); }