smith
September 2, 2021, 5:01pm
1
I created a bunch of animation clips that are intended for movement in two directions each Fwd/Bwd Left/Right but jme3 doesn’t support negative speeds, is there another way the get clips to cycle +/- and can getTime be used to smoothly swap and sync between clips at a given “frame”/time in a clip?
e.g. let say I have “run shoot fwd clip” and wanted to quickly change that to “run shoot dwn clip” (same length) but we want to do the swap such that if “run shoot fwd clip” was 80% done that “run shoot dwn clip” would smoothly start at 81% end and thereafter fully loop until another change is triggered
In my game the player controls bullet direction but the weapon direction may not always align immediately or fully with the bullets, since I chose to pose aiming in my hero character “stylized”
Note: I have animations for all four basic directions for some chosen weapon angles, it just seems like wasting effort since they were duplicated and mirrored on the timeline with no added posing in blender.
I have tried to “spit” getTime to the console to better understand it but I only get 0 or 1
sgold
September 2, 2021, 5:32pm
2
You can use the reverseAnimation()
method from the Wes library to create a reverse-time version of each clip:
AnimComposer composer = sinbadModelRoot.getControl(AnimComposer.class);
AnimClip forward = composer.getAnimClip("StandUpBack");
String reverseName = "LieDown";
AnimClip reverse = AnimationEdit.reverseAnimation(forward, reverseName);
composer.addAnimClip(reverse);
Or you can write your own custom animation control.
Or you can submit a pull request to add support for negative speeds in AnimComposer
.
smith
September 2, 2021, 6:08pm
3
I think I will give wes a go, as for adding it, it was previously supported in Jme3 then suddenly unsupported, I cannot recall the reasoning though, setting a negative speed now will mangle the model.
can you offer any advice on smoothing swapping animations mid play through when they share the same length like swap one animation at frame 14 and have the new one continue 15, 16, 17… (please note, I understand that jme’s system don’t function on the concept of frames per say, jus visualizing what I want to achieve)
my first post was actually two questions I messed it up by mixing up the paragraphs sorry
Ali_RS
September 2, 2021, 7:18pm
4
You can set negative speed using:
* @param length the desired length (in unscaled seconds, default=0)
*/
public void setLength(double length) {
this.length = length;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
if( speed < 0){
setForward(false);
} else {
setForward(true);
}
}
public AnimationMask getMask() {
return mask;
smith:
is there another way the get clips to cycle +/- and can getTime be used to smoothly swap and sync between clips at a given “frame”/time in a clip?
e.g. let say I have “run shoot fwd clip” and wanted to quickly change that to “run shoot dwn clip” (same length) but we want to do the swap such that if “run shoot fwd clip” was 80% done that “run shoot dwn clip” would smoothly start at 81% end and thereafter fully loop until another change is triggered
You can take a look at EffectControl and TweenAnimation from Lemur to see how it does this using the idea of channels.
And by the way, note that when you swap animation, transition to the new animation will already be smooth. You can control the transition using:
protected abstract void doInterpolate(double t);
public abstract Collection<HasLocalTransform> getTargets();
public abstract void collectTransform(HasLocalTransform target, Transform t, float weight, BlendableAction source);
public double getTransitionLength() {
return transitionLength;
}
public void setTransitionLength(double transitionLength) {
this.transitionLength = transitionLength;
this.transition.setLength(transitionLength);
}
protected float getTransitionWeight() {
return transitionWeight;
}
/**
* Create a shallow clone for the JME cloner.
1 Like
smith
September 2, 2021, 7:53pm
5
noted on all counts thanks for this
smith
September 2, 2021, 8:52pm
6
Ok tried to get lemur via git but I keep hitting this wall with gradle…will the last release work with the current jme3 release, getting to understand what need to do from the source, Lemur on it’s own seems interesting though
smith:
Blockquoteorg.gradle.tooling.GradleConnectionException: Could not create an instance of Tooling API implementation using the specified Gradle distribution ‘https://services.gradle.org/distributions/gradle-2.10-bin.zip ’.
at org.gradle.tooling.internal.consumer.loader.DefaultToolingImplementationLoader.create(DefaultToolingImplementationLoader.java:99)
at org.gradle.tooling.internal.consumer.loader.CachingToolingImplementationLoader.create(CachingToolingImplementationLoader.java:45)
at org.gradle.tooling.internal.consumer.loader.SynchronizedToolingImplementationLoader.create(SynchronizedToolingImplementationLoader.java:44)
at org.gradle.tooling.internal.consumer.connection.LazyConsumerActionExecutor.onStartAction(LazyConsumerActionExecutor.java:104)
at org.gradle.tooling.internal.consumer.connection.LazyConsumerActionExecutor.run(LazyConsumerActionExecutor.java:86)
at org.gradle.tooling.internal.consumer.connection.CancellableConsumerActionExecutor.run(CancellableConsumerActionExecutor.java:45)
at org.gradle.tooling.internal.consumer.connection.ProgressLoggingConsumerActionExecutor.run(ProgressLoggingConsumerActionExecutor.java:61)
at org.gradle.tooling.internal.consumer.connection.RethrowingErrorsConsumerActionExecutor.run(RethrowingErrorsConsumerActionExecutor.java:38)
at org.gradle.tooling.internal.consumer.async.DefaultAsyncConsumerActionExecutor.lambda$run$0(DefaultAsyncConsumerActionExecutor.java:55)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:832)
at org.gradle.tooling.internal.consumer.BlockingResultHandler.getResult(BlockingResultHandler.java:46)
at org.gradle.tooling.internal.consumer.DefaultModelBuilder.get(DefaultModelBuilder.java:51)
at org.gradle.tooling.internal.consumer.DefaultProjectConnection.getModel(DefaultProjectConnection.java:50)
at org.eclipse.buildship.core.internal.util.gradle.CompatProjectConnection.getModel(CompatProjectConnection.java:53)
at org.eclipse.buildship.core.internal.util.gradle.IdeAttachedProjectConnection.configureOperation(IdeAttachedProjectConnection.java:68)
at org.eclipse.buildship.core.internal.util.gradle.IdeAttachedProjectConnection.model(IdeAttachedProjectConnection.java:59)
at org.eclipse.buildship.core.internal.util.gradle.IdeAttachedProjectConnection.getModel(IdeAttachedProjectConnection.java:86)
at org.eclipse.buildship.core.internal.workspace.DefaultModelProvider.queryModel(DefaultModelProvider.java:115)
at org.eclipse.buildship.core.internal.workspace.DefaultModelProvider.lambda$null$0(DefaultModelProvider.java:50)
at org.eclipse.buildship.core.internal.DefaultGradleBuild$GradleConnectionOperation.runInToolingApi(DefaultGradleBuild.java:329)
at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager$WorkspaceRunnableAdapter.run(DefaultToolingApiOperationManager.java:58)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2292)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2317)
at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager.run(DefaultToolingApiOperationManager.java:39)
at org.eclipse.buildship.core.internal.DefaultGradleBuild.withConnection(DefaultGradleBuild.java:122)
at org.eclipse.buildship.core.internal.workspace.DefaultModelProvider.lambda$fetchModel$1(DefaultModelProvider.java:49)
at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4878)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4873)
at org.eclipse.buildship.core.internal.workspace.DefaultModelProvider.getFromCache(DefaultModelProvider.java:98)
at org.eclipse.buildship.core.internal.workspace.DefaultModelProvider.executeOperation(DefaultModelProvider.java:90)
at org.eclipse.buildship.core.internal.workspace.DefaultModelProvider.fetchModel(DefaultModelProvider.java:48)
at org.eclipse.buildship.ui.internal.wizard.project.ProjectPreviewWizardPage.fetchBuildEnvironment(ProjectPreviewWizardPage.java:451)
at org.eclipse.buildship.ui.internal.wizard.project.ProjectPreviewWizardPage.access$600(ProjectPreviewWizardPage.java:78)
at org.eclipse.buildship.ui.internal.wizard.project.ProjectPreviewWizardPage$UpdatePreviewOperation.runInToolingApi(ProjectPreviewWizardPage.java:476)
at org.eclipse.buildship.core.internal.operation.ToolingApiOperations$1.runInToolingApi(ToolingApiOperations.java:60)
at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager$WorkspaceRunnableAdapter.run(DefaultToolingApiOperationManager.java:58)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2292)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2317)
at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager.run(DefaultToolingApiOperationManager.java:39)
at org.eclipse.buildship.core.internal.operation.DefaultToolingApiOperationManager.run(DefaultToolingApiOperationManager.java:33)
at org.eclipse.buildship.ui.internal.wizard.project.ProjectPreviewWizardPage$4.run(ProjectPreviewWizardPage.java:311)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:122)
Caused by: org.gradle.internal.service.ServiceCreationException: Could not create service of type FileWatcherFactory using GlobalScopeServices.createFileWatcherFactory().
at org.gradle.internal.service.DefaultServiceRegistry$FactoryMethodService.invokeMethod(DefaultServiceRegistry.java:741)
at org.gradle.internal.service.DefaultServiceRegistry$FactoryService.create(DefaultServiceRegistry.java:695)
at org.gradle.internal.service.DefaultServiceRegistry$ManagedObjectProvider.getInstance(DefaultServiceRegistry.java:537)
at org.gradle.internal.service.DefaultServiceRegistry$SingletonService.get(DefaultServiceRegistry.java:577)
at org.gradle.internal.service.DefaultServiceRegistry$FactoryService.assembleParameters(DefaultServiceRegistry.java:705)
at org.gradle.internal.service.DefaultServiceRegistry$FactoryService.create(DefaultServiceRegistry.java:694)
at org.gradle.internal.service.DefaultServiceRegistry$ManagedObjectProvider.getInstance(DefaultServiceRegistry.java:537)
at org.gradle.internal.service.DefaultServiceRegistry$SingletonService.get(DefaultServiceRegistry.java:577)
at org.gradle.internal.service.DefaultServiceRegistry$FactoryService.assembleParameters(DefaultServiceRegistry.java:705)
at org.gradle.internal.service.DefaultServiceRegistry$FactoryService.create(DefaultServiceRegistry.java:694)
at org.gradle.internal.service.DefaultServiceRegistry$ManagedObjectProvider.getInstance(DefaultServiceRegistry.java:537)
at org.gradle.internal.service.DefaultServiceRegistry$SingletonService.get(DefaultServiceRegistry.java:577)
at org.gradle.internal.service.DefaultServiceRegistry.doGet(DefaultServiceRegistry.java:393)
at org.gradle.internal.service.DefaultServiceRegistry.get(DefaultServiceRegistry.java:374)
at org.gradle.tooling.internal.provider.DefaultConnection.initializeServices(DefaultConnection.java:83)
at org.gradle.tooling.internal.provider.DefaultConnection.configure(DefaultConnection.java:70)
at org.gradle.tooling.internal.consumer.connection.AbstractPost12ConsumerConnection.configure(AbstractPost12ConsumerConnection.java:37)
at org.gradle.tooling.internal.consumer.loader.DefaultToolingImplementationLoader.createConnection(DefaultToolingImplementationLoader.java:104)
at org.gradle.tooling.internal.consumer.loader.DefaultToolingImplementationLoader.create(DefaultToolingImplementationLoader.java:92)
at org.gradle.tooling.internal.consumer.loader.CachingToolingImplementationLoader.create(CachingToolingImplementationLoader.java:45)
at org.gradle.tooling.internal.consumer.loader.SynchronizedToolingImplementationLoader.create(SynchronizedToolingImplementationLoader.java:44)
at org.gradle.tooling.internal.consumer.connection.LazyConsumerActionExecutor.onStartAction(LazyConsumerActionExecutor.java:104)
at org.gradle.tooling.internal.consumer.connection.LazyConsumerActionExecutor.run(LazyConsumerActionExecutor.java:86)
at org.gradle.tooling.internal.consumer.connection.CancellableConsumerActionExecutor.run(CancellableConsumerActionExecutor.java:45)
at org.gradle.tooling.internal.consumer.connection.ProgressLoggingConsumerActionExecutor.run(ProgressLoggingConsumerActionExecutor.java:61)
at org.gradle.tooling.internal.consumer.connection.RethrowingErrorsConsumerActionExecutor.run(RethrowingErrorsConsumerActionExecutor.java:38)
at org.gradle.tooling.internal.consumer.async.DefaultAsyncConsumerActionExecutor.lambda$run$0(DefaultAsyncConsumerActionExecutor.java:55)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.IllegalArgumentException: Could not determine java version from ‘14.0.1’.
at org.gradle.api.JavaVersion.toVersion(JavaVersion.java:64)
at org.gradle.api.JavaVersion.current(JavaVersion.java:73)
at org.gradle.internal.filewatch.DefaultFileWatcherFactory.(DefaultFileWatcherFactory.java:37)
at org.gradle.internal.service.scopes.GlobalScopeServices.createFileWatcherFactory(GlobalScopeServices.java:260)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
at org.gradle.internal.service.DefaultServiceRegistry.invoke(DefaultServiceRegistry.java:426)
at org.gradle.internal.service.DefaultServiceRegistry.access$1200(DefaultServiceRegistry.java:61)
at org.gradle.internal.service.DefaultServiceRegistry$FactoryMethodService.invokeMethod(DefaultServiceRegistry.java:739)
… 32 more