Skip to content

Commit e309209

Browse files
authored
Merge pull request #248 from the3deer/fix/247
content manager fixed #247
2 parents 75bc656 + 084c4dc commit e309209

File tree

14 files changed

+579
-112
lines changed

14 files changed

+579
-112
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ ChangeLog
33

44
(f) fixed, (i) improved, (n) new feature
55

6+
- 4.1.1 (31/12/2024)
7+
- (i) Android SDK and dependencies updated (API 35)
8+
- (f) Fixed Android Content Manager Loader
9+
- (f) Fixed shader issue
610
- 4.1.0 (22/10/2024)
711
- (n) Gltf Animations
812
- (n) Android Preferences for Settings
913
- (n) Loader: Integrated Khronos repository
1014
- (i) Android view using Fragments
11-
- (i) Android SDK and dependencies updated
15+
- (i) Android SDK and dependencies updated (API 34)
1216
- 4.0.0 (04/09/2022)
1317
- (i) rebranding to org.the3deer
1418
- (i) master branch renamed to main

README.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The purpose of this application is to learn and share how to draw using OpenGL l
1313
* GLTF format (gltf): https://www.khronos.org/gltf/
1414

1515

16-
News (22/10/2024)
16+
News (31/12/2024)
1717
=================
1818

1919
* Gltf Animations :D
@@ -25,7 +25,7 @@ News (22/10/2024)
2525
Demo
2626
====
2727

28-
Checkout this to see the features of the application: https://www.youtube.com/watch?v=PV92DKohXXk
28+
Checkout this to see the features of the application (old video): https://www.youtube.com/watch?v=PV92DKohXXk
2929

3030

3131
Android Market
@@ -40,7 +40,7 @@ Notice
4040

4141
* Collada support is limited. Collada renderer currently supports a maximum of 60 bones.
4242
* In order to see models in 3D virtual reality, you need red-cyan and/or VR glasses
43-
* If you have any issue in general,please open an issue and attach model if possible, specifying Android version and Device model.
43+
* If you have any issue in general, please open an issue and attach model if possible, specifying Android version and Device model.
4444

4545

4646
About
@@ -52,27 +52,19 @@ The main purpose of this app is to show how to draw in android using the OpenGL
5252
So please, don't expect this application to be much richer or nicer than the ones already published in the app store,
5353
but at least it's opened to anyone who wants to contribute or don't want to start a similar project from scratch.
5454

55-
As this is my first android app and Im still learning the OpenGL 2.0 language, it is highly probable that there are bugs;
55+
As this is my first android app and Im still learning the OpenGL language, it is highly probable that there are bugs;
5656
but I will try to continue improving the app and adding more features. So please send me your comments, suggestions or
5757
complains by opening an [issue](https://github.com/the3deer/android-3D-model-viewer/issues).
5858

5959
The app comes with some included 3D models that have different licenses.
6060

6161

62-
Whats next
63-
==========
64-
65-
* Improve support for glTF standard format
66-
* VR without glasses (on hold)
67-
* Augmented reality
68-
69-
7062
Features
7163
========
7264

73-
- [x] Supports >= Android 4.1 (Ice Cream Sandwich) - Min API Level 16 -> Target API Level 31
74-
- [x] OpenGL ES 2.0 API
75-
- [x] Multiple Formats:
65+
- [x] Supports >= Android Lollipop 5.0 (Min API Level 21 -> Target API Level 35)
66+
- [x] Android API: OpenGL ES 2.0, Fragments, Preferences, Content Manager
67+
- [x] 3D Formats:
7668
- [x] OBJ (wavefront)
7769
- [x] STL (STereoLithography)
7870
- [x] DAE (Collada-BETA)
@@ -115,6 +107,10 @@ You can install the application in either of these ways:
115107
* APK: [app-release.apk](app/build/outputs/apk/release/app-release.apk)
116108
* Source code: clone the repository, compile with gradle and install with adb
117109

110+
Once you open the application, you can load any of the supported model formats.
111+
112+
* It's recommended to have all the model resources packed in a .zip file
113+
118114

119115
Compilation
120116
===========

app/build.gradle

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ plugins {
33
}
44

55
android {
6-
compileSdk 34
6+
compileSdk 35
77

88
defaultConfig {
99
applicationId "org.andresoviedo.dddmodel2"
1010
minSdk 21
11-
targetSdk 34
11+
targetSdk 35
1212

1313
multiDexEnabled true
1414
}
@@ -41,11 +41,11 @@ android {
4141

4242
dependencies {
4343
implementation 'javax.inject:javax.inject:1'
44-
implementation 'androidx.core:core:1.13.1'
45-
implementation 'androidx.fragment:fragment:1.8.3'
46-
implementation 'androidx.lifecycle:lifecycle-viewmodel-android:2.8.6'
44+
implementation 'androidx.core:core:1.15.0'
45+
implementation 'androidx.fragment:fragment:1.8.5'
46+
implementation 'androidx.lifecycle:lifecycle-viewmodel-android:2.8.7'
4747
implementation 'androidx.preference:preference:1.2.1'
48-
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
48+
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
4949
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
5050
implementation 'com.google.android.material:material:1.12.0'
5151
implementation project(':engine')

app/debug/output-metadata.json

Lines changed: 0 additions & 20 deletions
This file was deleted.

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools"
4-
android:versionCode="35"
5-
android:versionName="5.0.0">
4+
android:versionCode="36"
5+
android:versionName="4.1.1">
66

77
<uses-sdk
88
tools:overrideLibrary="android.support.compat, android.arch.lifecycle" />
@@ -20,7 +20,10 @@
2020
android:label="@string/app_name"
2121
android:theme="@style/AppTheme"
2222
android:largeHeap="true"
23-
android:requestLegacyExternalStorage="true">
23+
android:requestLegacyExternalStorage="true"
24+
android:allowCrossUidActivitySwitchFromBelow="false"
25+
tools:targetApi="35">
26+
2427
<activity
2528
android:name="org.the3deer.app.model3D.MainActivity"
2629
android:exported="true"

app/src/main/java/org/the3deer/app/model3D/MainActivity.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package org.the3deer.app.model3D;
22

33
import android.content.DialogInterface;
4+
import android.content.Intent;
45
import android.net.Uri;
56
import android.os.Bundle;
67
import android.util.Log;
78
import android.widget.Toast;
89

910
import androidx.activity.OnBackPressedCallback;
11+
import androidx.activity.result.ActivityResultLauncher;
12+
import androidx.activity.result.contract.ActivityResultContracts;
13+
import androidx.annotation.Nullable;
1014
import androidx.appcompat.app.AppCompatActivity;
1115
import androidx.fragment.app.Fragment;
1216
import androidx.lifecycle.ViewModelProvider;
@@ -15,6 +19,8 @@
1519
import org.the3deer.android_3d_model_engine.ModelEngine;
1620
import org.the3deer.android_3d_model_engine.ModelFragment;
1721
import org.the3deer.android_3d_model_engine.ModelViewModel;
22+
import org.the3deer.app.model3D.view.HelpDialogFragment;
23+
import org.the3deer.app.model3D.view.LoadContentDialog;
1824
import org.the3deer.app.model3D.view.MainDialogFragment;
1925

2026
/**
@@ -33,6 +39,9 @@ public class MainActivity extends AppCompatActivity implements DialogInterface.O
3339
// variables
3440
private Fragment fragmentMenu;
3541
private ModelViewModel viewModel;
42+
private ActivityResultLauncher<String> mGetContent;
43+
44+
private LoadContentDialog loadContentDialog = new LoadContentDialog(this);
3645

3746
@Override
3847
protected void onCreate(Bundle savedInstanceState) {
@@ -54,7 +63,11 @@ protected void onCreate(Bundle savedInstanceState) {
5463
// Do something with the result.
5564
if ("load".equals(action)) {
5665
showDialog();
57-
} else if ("back".equals(action)){
66+
} else if ("help".equals(action)){
67+
showHelpDialog();
68+
} else if ("pick".equals(action)){
69+
loadContentDialog.start();
70+
} else if ("back".equals(action)){
5871
showDialog();
5972
}
6073
});
@@ -66,18 +79,38 @@ public void handleOnBackPressed() {
6679
}
6780
});
6881

82+
ActivityResultContracts.GetContent contract = loadContentDialog.getActivityContract();
83+
84+
mGetContent = registerForActivityResult(contract,
85+
uri -> {
86+
try {
87+
// Handle the returned Uri
88+
Log.i(TAG, "Uri: " + uri);
89+
loadContentDialog.load(uri);
90+
} catch (Exception e) {
91+
Log.e(TAG, "Exception loading uri: " + uri, e);
92+
Toast.makeText(getApplication(), "Problem loading " + uri.toString()+
93+
"\n"+e.getMessage(), Toast.LENGTH_LONG).show();
94+
}
95+
});
96+
6997
showDialog();
7098
//launchModelRendererActivity(Uri.parse("android://org.the3deer.dddmodel2/assets/models/teapot.obj"), "0");
7199
}
72100

101+
@Override
102+
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
103+
super.onActivityResult(requestCode, resultCode, data);
104+
}
73105

74-
75-
/*@Override
106+
/*@Override
76107
public void onBackPressed() {
77108
super.onBackPressed();
78109
showDialog();
79110
}*/
80111

112+
113+
81114
private void showDialog(){
82115
//Log.i("MainActivity", "setUp: "+getSupportFragmentManager().findFragmentByTag("model"));
83116
if (getSupportFragmentManager().findFragmentByTag("dialog") == null) {
@@ -86,11 +119,20 @@ private void showDialog(){
86119
}
87120
}
88121

122+
public void showHelpDialog() {
123+
HelpDialogFragment fragment = HelpDialogFragment.newInstance(R.string.alert_dialog_help_title);
124+
fragment.show(getSupportFragmentManager(), "help");
125+
}
126+
89127
@Override
90128
public void onDismiss(DialogInterface dialog) {
91129
//showDialog();
92130
}
93131

132+
public void pick(String mimeType){
133+
this.mGetContent.launch(mimeType);
134+
}
135+
94136
private void launchModelRendererActivity(Uri uri, String type) {
95137

96138
try {
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package org.the3deer.app.model3D.view;
2+
3+
import android.content.DialogInterface;
4+
import android.content.Intent;
5+
import android.os.Bundle;
6+
import android.util.Log;
7+
import android.widget.Toast;
8+
9+
import org.andresoviedo.dddmodel2.R;
10+
import org.the3deer.android_3d_model_engine.ModelFragment;
11+
import org.the3deer.app.model3D.demo.EarCutDemoFragment;
12+
import org.the3deer.app.model3D.demo.GlyphsDemoFragment;
13+
import org.the3deer.util.android.ContentUtils;
14+
import org.the3deer.util.android.DialogFragment;
15+
import org.the3deer.util.view.TextActivity;
16+
17+
public class HelpDialogFragment extends DialogFragment {
18+
19+
private enum Action {
20+
DEMOS, HELP, ABOUT
21+
}
22+
23+
public static HelpDialogFragment newInstance(int title) {
24+
HelpDialogFragment frag = new HelpDialogFragment();
25+
Bundle args = new Bundle();
26+
args.putInt("title", title);
27+
args.putInt("items", R.array.dialog_help_items);
28+
frag.setArguments(args);
29+
return frag;
30+
}
31+
32+
@Override
33+
public void onClick(DialogInterface dialogI, int position) {
34+
try {
35+
Action action = Action.values()[position];
36+
switch (action) {
37+
case DEMOS:
38+
ContentUtils.showListDialog(activity, "Demos List", new String[]{"Simple Objects", "GUI", "Geometry"}, (DialogInterface dialog, int which) -> {
39+
if (which == 0) {
40+
ModelFragment modelFragment2 = ModelFragment.newInstance(null, null, true);
41+
activity.getSupportFragmentManager().beginTransaction()
42+
.replace(R.id.main_container, modelFragment2, "demo_0")
43+
.setReorderingAllowed(true)
44+
.addToBackStack(null)
45+
.commit();
46+
dismiss();
47+
} else if (which == 1) {
48+
ModelFragment modelFragment2 = new GlyphsDemoFragment();
49+
activity.getSupportFragmentManager().beginTransaction()
50+
.replace(R.id.main_container, modelFragment2, "demo_1")
51+
.setReorderingAllowed(true)
52+
.addToBackStack(null)
53+
.commit();
54+
dismiss();
55+
} else if (which == 2) {
56+
ModelFragment modelFragment2 = new EarCutDemoFragment();
57+
activity.getSupportFragmentManager().beginTransaction()
58+
.replace(R.id.main_container, modelFragment2, "demo_2")
59+
.setReorderingAllowed(true)
60+
.addToBackStack(null)
61+
.commit();
62+
dismiss();
63+
}
64+
});
65+
break;
66+
case HELP:
67+
Intent helpIntent = new Intent(activity, TextActivity.class);
68+
helpIntent.putExtra("title", items[position]);
69+
helpIntent.putExtra("text", getResources().getString(R.string.help_text));
70+
startActivity(helpIntent);
71+
break;
72+
case ABOUT:
73+
Intent aboutIntent = new Intent(activity, TextActivity.class);
74+
aboutIntent.putExtra("title", items[position]);
75+
aboutIntent.putExtra("text", getResources().getString(R.string.about_text));
76+
startActivity(aboutIntent);
77+
break;
78+
default:
79+
Toast.makeText(activity, "Unrecognized action '" + action + "'",
80+
Toast.LENGTH_LONG).show();
81+
break;
82+
}
83+
} catch (Exception ex) {
84+
Log.e("MainDialogFragment",ex.getMessage(),ex);
85+
Toast.makeText(activity, ex.getMessage(), Toast.LENGTH_LONG).show();
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)