How to use
In this section we will discuss how you can use ApertusVR's main features from Android and Java
The wrapper classes are placed in the
org.apertusvr
package. For each ApertusVR entity type there's a corresponding Java wrapper class. Also there are a wrapper classes for the manager classes (e.g. ape::EventManager
, ape::SceneManager
)and ape::Event
and there are several supporting classes (e.g. apeColor
, apeVector3
). To be able to cast the interfaces, we ha a builder Java interface (apeBuilder
) too.Just like using the C++ interface, the user can connect to various events (fired by ApertusVR) from Java code. To do that, we need to implement the
apeEventCallback
function:class MyEventCallback implements apeEventCallback {
@Override
public void onEvent(apeEvent event) {
// do sth with event
}
}
We also have to create an instance of the
MyEventCallback
class, e.g.MyEventCallback eventCallback = new MyEventCallback();
After instantiation, the connection works simply with the usage of
apeManager
's connectEvent(...)
function. E.g., to be able to listen NODE
events, just type:apeEventManager.connectEvent(apeEvent.Group.NODE, eventCallback);
To get an insight of what actually happens here, let us discuss the details! When the user connects an event, the
apeEventManager
(which is a static class) puts this eventCallback
into a map:private static Map<apeEvent.Group, LinkedList<apeEventCallback>> mEventMap
The app developer also creates a
FrameCallback
class, which implements Android's built in Choreographer.FrameCallback
. Like in the following code block:class FrameCallback implements Choreographer.FrameCallback {
@Override
public void doFrame(long frameTimeNanos) {
choreographer.postFrameCallback(this);
if (apeSystem.isRunning()) {
ApertusJNI.processEventDoubleQueue();
}
}
}
This will parse all the events fired in the C++ side, during the last frame. The ApertusJNI member function called
processEventDoubleQueue()
is a JNI-function, which calls back to Java with apeEventManager
's fireEvent()
function, which will call the onEvent(apeEvent)
function of our apeEventCallback
implementation, if its instance is connected to the event's group (so the implementation object can be found under the apeEvent.Group.NODE
key in the map).As it was written before, for each entity class in ApertusVR we have a corresponding Java class. The member functions and the class hierarchies on the Java side are the same, as they are on the C++ side. Therefore the API does not differ much, but there are tiny differences between the two. We will go through everything you need, to use ApertusVR entities from Java.
In C++, knowing the entity's name, we ask the
ape::ISceneManager
to give us a weak pointer. Then we use the lock()
function to access it. After calling lock()
, we can also cast the resulted shared_ptr
to the proper type (ape::Entity::Type
), if we know what the entity's type should be.
When using ApertusVR from Java, we just use the interface's constructor to get access to an entity, then we check with the isValid()
function, that we can actually lock it in C++.E.g. assume, that we want to access an
apeFileGeometry
entity we know about, with the name of "FooBar"
, and our goal is to query its OwnerID
. The procedure goes something like on the following code example:String fooBarName = "FooBar";
apeFileGeometry fooBarGeometry = new apeFileGeometry(fooBarName);
if (fooBarGeometry.isValid()) {
String ownerID = fooBarGeometry.getOwnerID();
}
The following figure summarizes the procedure executed in the background:
This is the way in 90% of the cases. However, what if we don't know already the type of the entity, and only its name is given. In this case, we can use the
apeSceneManager
interface:String fooBarName = "FooBar";
apeEntity fooBarEntity = apeSceneManager.getEntity(fooBarName);
if (fooBarEntity != null && fooBarEntity.isValid()) {
apeEntity.Type fooBarType = fooBarEntity.getType();
if (fooBarType == apeEntity.Type.GEOMETRY_FILE) {
apeFileGeometry fooBarGeometry = new apeFileGeometry(fooBarName);
// ...
}
}
The next question is, how can we create entities in Java? Easy. Just use the
apeSceneManager
interface!:String fooBarName = "FooBar";
apeEntity.Type fooBarType = apeEntity.Type.GEOMETRY_FILE;
boolean fooBarIsReplicate = false;
String fooBarOwner = "FooBarOwner";
apeEntity fooBarEntity = apeSceneManager.createEntity(
fooBarName, fooBarType, fooBarIsReplicate, fooBarOwner);
Okay, then how do we cast it to our needs? We wanted
apeFileGeometry
interface, not apeEntity
.
This is where the apeBuilder
interface come in! The apeEntity
abstract class has a member function called cast
:public <apeType extends apeEntity> apeType cast(apeBuilder<apeType> builder)
Providing a proper builder class (which implements the
apeBuilder
interface), we can cast our apeEntity
to any given type extended from it. In the example, we just type:apeFileGeometry fooBarGeometry = Objects.requireNonNull(
apeSceneManager.createEntity(
fooBarName,
fooBarType,
fooBarIsReplicate,
fooBarOwner))
.cast(new apeFileGeometry.FileGeometryBuilder());
Or an alternative way is to instance an other
apeFileGeometry
entity with the apeEntity
's name you got from apeSceneManager
(like you saw it in the former sub-subsection).Deleting an entity in Java is the same as in C++, an example is presented below:
String entityName = "FooBar";
apeSceneManager.deleteEntity(entityName);
Last modified 2yr ago