diff --git a/CHANGELOG.md b/CHANGELOG.md index b160731..64ed03f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [5-r.1-beta.3] - 2024-01-18 + +### Added + +* Add exception catching and error logging handling when an exception is thrown while loading a JSON file. + +### Changed + +* Change the compile and target SDK version of Android OS to 14.0 (API 34). + * Upgrade the version of Android Gradle Plugin from 8.0.2 to 8.1.1. + * Upgrade the version of Gradle from 8.1.1 to 8.2. + * Change the minimum version of Android Studio to Hedgehog(2023.1.1). +* Change the visibility of the `CubismPhysicsInternal` and `CubismPhysicsJson` classes to `public`. + +### Fixed + +* Fix an issue where models with a specific number of masks could not be drawn correctly. +* Replace deprecated notation in `build.gradle`. + + ## [5-r.1-beta.2] - 2023-09-28 ### Added @@ -134,6 +154,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * New released! +[5-r.1-beta.3]: https://github.com/Live2D/CubismJavaFramework/compare/5-r.1-beta.2...5-r.1-beta.3 [5-r.1-beta.2]: https://github.com/Live2D/CubismJavaFramework/compare/5-r.1-beta.1...5-r.1-beta.2 [5-r.1-beta.1]: https://github.com/Live2D/CubismJavaFramework/compare/4-r.1...5-r.1-beta.1 [4-r.1]: https://github.com/Live2D/CubismJavaFramework/compare/4-r.1-beta.4...4-r.1 diff --git a/build.gradle b/build.gradle index 7ac51a9..0fc313e 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.0.2' + classpath 'com.android.tools.build:gradle:8.1.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/framework/build.gradle b/framework/build.gradle index f847aa5..70611c0 100644 --- a/framework/build.gradle +++ b/framework/build.gradle @@ -4,7 +4,7 @@ plugins { android { namespace = "com.live2d.sdk.cubism.framework" - compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger() + compileSdk PROP_COMPILE_SDK_VERSION.toInteger() defaultConfig { minSdkVersion PROP_MIN_SDK_VERSION diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/model/CubismUserModel.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/model/CubismUserModel.java index ff51778..4ad255b 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/model/CubismUserModel.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/model/CubismUserModel.java @@ -327,7 +327,12 @@ protected CubismMotion loadMotion( byte[] buffer, IFinishedMotionCallback onFinishedMotionHandler ) { - return CubismMotion.create(buffer, onFinishedMotionHandler); + try { + return CubismMotion.create(buffer, onFinishedMotionHandler); + } catch (Exception e) { + cubismLogError("Failed to loadMotion(). %s", e.getMessage()); + return null; + } } /** @@ -337,7 +342,7 @@ protected CubismMotion loadMotion( * @return motion class */ protected CubismMotion loadMotion(byte[] buffer) { - return CubismMotion.create(buffer, null); + return loadMotion(buffer, null); } /** @@ -347,7 +352,12 @@ protected CubismMotion loadMotion(byte[] buffer) { * @return motion class */ protected CubismExpressionMotion loadExpression(final byte[] buffer) { - return CubismExpressionMotion.create(buffer); + try { + return CubismExpressionMotion.create(buffer); + } catch (Exception e) { + cubismLogError("Failed to loadExpressionMotion(). %s", e.getMessage()); + return null; + } } /** @@ -356,7 +366,11 @@ protected CubismExpressionMotion loadExpression(final byte[] buffer) { * @param buffer a buffer where pose3.json is loaded. */ protected void loadPose(final byte[] buffer) { - pose = CubismPose.create(buffer); + try { + pose = CubismPose.create(buffer); + } catch (Exception e) { + cubismLogError("Failed to loadPose(). %s", e.getMessage()); + } } /** @@ -365,7 +379,11 @@ protected void loadPose(final byte[] buffer) { * @param buffer a buffer where physics3.json is loaded. */ protected void loadPhysics(final byte[] buffer) { - physics = CubismPhysics.create(buffer); + try { + physics = CubismPhysics.create(buffer); + } catch (Exception e) { + cubismLogError("Failed to loadPhysics(). %s", e.getMessage()); + } } /** @@ -374,7 +392,11 @@ protected void loadPhysics(final byte[] buffer) { * @param buffer a buffer where userdata3.json is loaded. */ protected void loadUserData(final byte[] buffer) { - modelUserData = CubismModelUserData.create(buffer); + try { + modelUserData = CubismModelUserData.create(buffer); + } catch (Exception e) { + cubismLogError("Failed to loadUserData(). %s", e.getMessage()); + } } /** diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/physics/CubismPhysicsInternal.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/physics/CubismPhysicsInternal.java index 99b9598..18532d9 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/physics/CubismPhysicsInternal.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/physics/CubismPhysicsInternal.java @@ -16,7 +16,7 @@ /** * Internal data of CubismPhysics. */ -class CubismPhysicsInternal { +public class CubismPhysicsInternal { /** * Types of physics operations to be applied. */ diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/physics/CubismPhysicsJson.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/physics/CubismPhysicsJson.java index 62ca1ae..01f00eb 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/physics/CubismPhysicsJson.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/physics/CubismPhysicsJson.java @@ -15,7 +15,7 @@ /** * A manager of physics3.json. */ -class CubismPhysicsJson { +public class CubismPhysicsJson { /** * Constructor * diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ACubismClippingContext.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ACubismClippingContext.java index aa10385..bf9f461 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ACubismClippingContext.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ACubismClippingContext.java @@ -102,7 +102,7 @@ public void addClippedDrawable(int drawableIndex) { /** * RGBAのいずれのチャンネルにこのクリップを配置するか(0:R, 1:G, 2:B, 3:A) */ - public int layoutChannelNo; + public int layoutChannelIndex; /** * マスク用チャンネルのどの領域にマスクを入れるか(View座標-1..1, UVは0..1に直す) diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ACubismClippingManager.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ACubismClippingManager.java index be86d0d..6ef9c72 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ACubismClippingManager.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ACubismClippingManager.java @@ -257,7 +257,7 @@ public void setupLayoutBounds(int usingClipCount) { for (int index = 0; index < clippingContextListForMask.size(); index++) { T_ClippingContext cc = clippingContextListForMask.get(index); - cc.layoutChannelNo = 0; // どうせ毎回消すので固定で良い + cc.layoutChannelIndex = 0; // どうせ毎回消すので固定で良い cc.layoutBounds.setX(0.0f); cc.layoutBounds.setY(0.0f); cc.layoutBounds.setWidth(1.0f); @@ -272,25 +272,31 @@ public void setupLayoutBounds(int usingClipCount) { // ひとつのRenderTextureを極力いっぱいに使ってマスクをレイアウトする。 // マスクグループの数が4以下ならRGBA各チャンネルに1つずつマスクを配置し、5以上6以下ならRGBAを2,2,1,1と配置する。 - int countPerSheetDiv = usingClipCount / renderTextureCount; // レンダーテクスチャ1枚あたり何枚割り当てるか - int countPerSheetMod = usingClipCount % renderTextureCount; // この番号のレンダーテクスチャまでに1つずつ配分する。 + // NOTE: 1枚に割り当てるマスクの分割数を取りたいため、小数点は切り上げる。 + final int countPerSheetDiv = (usingClipCount + renderTextureCount - 1) / renderTextureCount; // レンダーテクスチャ1枚あたり何枚割り当てるか + final int reduceLayoutTextureCount = usingClipCount % renderTextureCount; // レイアウトの数を1枚減らすレンダーテクスチャの数(この数だけのレンダーテクスチャが対象)。 // RGBAを順番に使っていく。 - final int div = countPerSheetDiv / COLOR_CHANNEL_COUNT; // 1チャンネルに配置する基本のマスク個数 - final int mod = countPerSheetDiv % COLOR_CHANNEL_COUNT; // 余り、この番号のチャンネルまでに1つずつ配分する + final int divCount = countPerSheetDiv / COLOR_CHANNEL_COUNT; // 1チャンネルに配置する基本のマスク個数 + final int modCount = countPerSheetDiv % COLOR_CHANNEL_COUNT; // 余り、この番号のチャンネルまでに1つずつ配分する(インデックスではない) // RGBAそれぞれのチャンネルを用意していく(0:R , 1:G , 2:B, 3:A, ) int curClipIndex = 0; // 順番に設定していく - for (int renderTextureNo = 0; renderTextureNo < renderTextureCount; renderTextureNo++) { - for (int channelNo = 0; channelNo < COLOR_CHANNEL_COUNT; channelNo++) { + for (int renderTextureIndex = 0; renderTextureIndex < renderTextureCount; renderTextureIndex++) { + for (int channelIndex = 0; channelIndex < COLOR_CHANNEL_COUNT; channelIndex++) { // このチャンネルにレイアウトする数 - int layoutCount = div + (channelNo < mod ? 1 : 0); + // NOTE: レイアウト数 = 1チャンネルに配置する基本のマスク + 余りのマスクを置くチャンネルなら1つ追加 + int layoutCount = divCount + (channelIndex < modCount ? 1 : 0); - // このレンダーテクスチャにまだ割り当てられていなければ追加する - final int checkChannelNo = mod + 1 >= COLOR_CHANNEL_COUNT ? 0 : mod + 1; - if (layoutCount < layoutCountMaxValue && channelNo == checkChannelNo) { - layoutCount += renderTextureNo < countPerSheetMod ? 1 : 0; + // レイアウトの数を1枚減らす場合にそれを行うチャンネルを決定 + // divが0の時は正常なインデックスの範囲になるように調整 + final int checkChannelIndex = modCount + (divCount < 1 ? -1 : 0); + + // 今回が対象のチャンネルかつ、レイアウトの数を1枚減らすレンダーテクスチャが存在する場合 + if (channelIndex == checkChannelIndex && reduceLayoutTextureCount > 0) { + // 現在のレンダーテクスチャが、対象のレンダーテクスチャであればレイアウトの数を1枚減らす。 + layoutCount -= !(renderTextureIndex < reduceLayoutTextureCount) ? 1 : 0; } // 分割方法を決定する。 @@ -299,7 +305,7 @@ public void setupLayoutBounds(int usingClipCount) { } else if (layoutCount == 1) { // 全てをそのまま使う。 T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++); - cc.layoutChannelNo = channelNo; + cc.layoutChannelIndex = channelIndex; csmRectF bounds = cc.layoutBounds; bounds.setX(0.0f); @@ -307,13 +313,13 @@ public void setupLayoutBounds(int usingClipCount) { bounds.setWidth(1.0f); bounds.setHeight(1.0f); - cc.bufferIndex = renderTextureNo; + cc.bufferIndex = renderTextureIndex; } else if (layoutCount == 2) { for (int i = 0; i < layoutCount; i++) { final int xpos = i % 2; T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++); - cc.layoutChannelNo = channelNo; + cc.layoutChannelIndex = channelIndex; csmRectF bounds = cc.layoutBounds; // UVを2つに分解して使う @@ -322,7 +328,7 @@ public void setupLayoutBounds(int usingClipCount) { bounds.setWidth(0.5f); bounds.setHeight(1.0f); - cc.bufferIndex = renderTextureNo; + cc.bufferIndex = renderTextureIndex; } } else if (layoutCount <= 4) { // 4分割して使う @@ -331,7 +337,7 @@ public void setupLayoutBounds(int usingClipCount) { final int ypos = i / 2; T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++); - cc.layoutChannelNo = channelNo; + cc.layoutChannelIndex = channelIndex; csmRectF bounds = cc.layoutBounds; bounds.setX(xpos * 0.5f); @@ -339,7 +345,7 @@ public void setupLayoutBounds(int usingClipCount) { bounds.setWidth(0.5f); bounds.setHeight(0.5f); - cc.bufferIndex = renderTextureNo; + cc.bufferIndex = renderTextureIndex; } } else if (layoutCount <= layoutCountMaxValue) { // 9分割して使う @@ -348,7 +354,7 @@ public void setupLayoutBounds(int usingClipCount) { final int ypos = i / 3; T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++); - cc.layoutChannelNo = channelNo; + cc.layoutChannelIndex = channelIndex; csmRectF bounds = cc.layoutBounds; bounds.setX(xpos / 3.0f); @@ -356,7 +362,7 @@ public void setupLayoutBounds(int usingClipCount) { bounds.setWidth(1.0f / 3.0f); bounds.setHeight(1.0f / 3.0f); - cc.bufferIndex = renderTextureNo; + cc.bufferIndex = renderTextureIndex; } } // マスクの制限枚数を超えた場合の処理 @@ -376,7 +382,7 @@ public void setupLayoutBounds(int usingClipCount) { // もちろん描画結果はろくなことにならない。 for (int i = 0; i < layoutCount; i++) { T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++); - cc.layoutChannelNo = 0; + cc.layoutChannelIndex = 0; csmRectF bounds = cc.layoutBounds; bounds.setX(0.0f); @@ -407,8 +413,8 @@ public int getRenderTextureCount() { } @Override - public CubismRenderer.CubismTextureColor getChannelFlagAsColor(int channelNo) { - return channelColors.get(channelNo); + public CubismRenderer.CubismTextureColor getChannelFlagAsColor(int channelIndex) { + return channelColors.get(channelIndex); } /** diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ICubismClippingManager.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ICubismClippingManager.java index 3a4f03f..7829f2a 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ICubismClippingManager.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/ICubismClippingManager.java @@ -96,8 +96,8 @@ void createMatrixForMask( /** * カラーチャンネル(RGBA)のフラグを取得する。 * - * @param channelNo カラーチャンネル(RGBA)の番号(0:R, 1:G, 2:B, 3:A) + * @param channelIndex カラーチャンネル(RGBA)の番号(0:R, 1:G, 2:B, 3:A) * @return カラーチャンネルのフラグ */ - CubismRenderer.CubismTextureColor getChannelFlagAsColor(int channelNo); + CubismRenderer.CubismTextureColor getChannelFlagAsColor(int channelIndex); } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismRendererAndroid.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismRendererAndroid.java index 019b834..29caa7f 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismRendererAndroid.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismRendererAndroid.java @@ -123,11 +123,11 @@ public void close() { /** * Bind processing of OpenGL textures. * - * @param modelTextureNo number of the model texture to set - * @param glTextureNo number of the OpenGL texture to bind + * @param modelTextureIndex number of the model texture to set + * @param glTextureIndex number of the OpenGL texture to bind */ - public void bindTexture(int modelTextureNo, int glTextureNo) { - textures.put(modelTextureNo, glTextureNo); + public void bindTexture(int modelTextureIndex, int glTextureIndex) { + textures.put(modelTextureIndex, glTextureIndex); areTexturesChanged = true; } diff --git a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismShaderAndroid.java b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismShaderAndroid.java index 54c2f7e..2f7d719 100644 --- a/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismShaderAndroid.java +++ b/framework/src/main/java/com/live2d/sdk/cubism/framework/rendering/android/CubismShaderAndroid.java @@ -167,11 +167,11 @@ public void setupShaderProgramForDraw( ); // Set used color channel. - final int channelNumber = renderer.getClippingContextBufferForDraw().layoutChannelNo; + final int channelIndex = renderer.getClippingContextBufferForDraw().layoutChannelIndex; CubismRenderer.CubismTextureColor colorChannel = renderer .getClippingContextBufferForDraw() .getClippingManager() - .getChannelFlagAsColor(channelNumber); + .getChannelFlagAsColor(channelIndex); glUniform4f( shaderSet.uniformChannelFlagLocation, colorChannel.r, @@ -290,11 +290,11 @@ public void setupShaderProgramForMask( ); // channels - final int channelNumber = renderer.getClippingContextBufferForMask().layoutChannelNo; + final int channelIndex = renderer.getClippingContextBufferForMask().layoutChannelIndex; CubismRenderer.CubismTextureColor colorChannel = renderer .getClippingContextBufferForMask() .getClippingManager() - .getChannelFlagAsColor(channelNumber); + .getChannelFlagAsColor(channelIndex); glUniform4f( shaderSet.uniformChannelFlagLocation, diff --git a/gradle.properties b/gradle.properties index 8e331cf..83ae449 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,8 +18,8 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Android SDK version that will be used as the compiled project -PROP_COMPILE_SDK_VERSION=33 +PROP_COMPILE_SDK_VERSION=34 # Android SDK version that will be used as the earliest version of android this application can run on PROP_MIN_SDK_VERSION=21 # Android SDK version that will be used as the latest version of android this application has been tested on -PROP_TARGET_SDK_VERSION=33 +PROP_TARGET_SDK_VERSION=34 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9860545..27fbb4c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue Jul 11 18:25:17 JST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists