This is an automated email from the ASF dual-hosted git repository.
jsorel pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new 09c39185cf feat(Geometry): add scene animation classes
09c39185cf is described below
commit 09c39185cfcaec78cb10c52d71c36c65f2703ffb
Author: jsorel <[email protected]>
AuthorDate: Thu Mar 5 15:15:36 2026 +0100
feat(Geometry): add scene animation classes
---
.../org/apache/sis/geometries/math/Cursor.java | 2 +-
.../sis/geometries/math/CursorUnmodifiable.java | 8 +-
.../org/apache/sis/geometries/scene/Animation.java | 80 +++++++++++++++
.../sis/geometries/scene/AnimationSampler.java | 76 ++++++++++++++
.../apache/sis/geometries/scene/MorphTarget.java | 110 +++++++++++++++++++++
.../org/apache/sis/geometries/scene/SceneNode.java | 29 ++++++
.../main/org/apache/sis/geometries/scene/Skin.java | 90 +++++++++++++++++
.../org/apache/sis/geometries/scene/Surface.java | 12 ++-
8 files changed, 401 insertions(+), 6 deletions(-)
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Cursor.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Cursor.java
index f2c3bc6b5f..81c24a1b32 100644
---
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Cursor.java
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Cursor.java
@@ -25,7 +25,7 @@ package org.apache.sis.geometries.math;
*/
public interface Cursor {
- Tuple samples();
+ Tuple<?> samples();
/**
* Get the current tuple coordinate.
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/CursorUnmodifiable.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/CursorUnmodifiable.java
index 674cb12976..f4df8278e3 100644
---
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/CursorUnmodifiable.java
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/CursorUnmodifiable.java
@@ -27,8 +27,8 @@ import org.apache.sis.util.ArgumentChecks;
final class CursorUnmodifiable implements Cursor {
private final Cursor parent;
- private Tuple previous;
- private Tuple t;
+ private Tuple<?> previous;
+ private Tuple<?> t;
public CursorUnmodifiable(Cursor parent) {
ArgumentChecks.ensureNonNull("parent", parent);
@@ -36,8 +36,8 @@ final class CursorUnmodifiable implements Cursor {
}
@Override
- public Tuple samples() {
- Tuple cdt = parent.samples();
+ public Tuple<?> samples() {
+ Tuple<?> cdt = parent.samples();
if (t == null || previous != cdt) {
t = new TupleUnmodifiable(cdt);
previous = cdt;
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Animation.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Animation.java
new file mode 100644
index 0000000000..499bca9a28
--- /dev/null
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Animation.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.geometries.scene;
+
+import java.util.Objects;
+
+/**
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class Animation {
+
+ public static final String TARGET_TRANSLATION = "translation";
+ public static final String TARGET_ROTATION = "rotation";
+ public static final String TARGET_SCALE = "scale";
+ public static final String TARGET_WEIGHTS = "weights";
+
+ private String target;
+ private AnimationSampler sampler;
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public AnimationSampler getSampler() {
+ return sampler;
+ }
+
+ public void setSampler(AnimationSampler sampler) {
+ this.sampler = sampler;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 53 * hash + Objects.hashCode(this.target);
+ hash = 53 * hash + Objects.hashCode(this.sampler);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Animation other = (Animation) obj;
+ if (!Objects.equals(this.target, other.target)) {
+ return false;
+ }
+ if (!Objects.equals(this.sampler, other.sampler)) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/AnimationSampler.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/AnimationSampler.java
new file mode 100644
index 0000000000..76eed9070b
--- /dev/null
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/AnimationSampler.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.geometries.scene;
+
+import java.util.Objects;
+import org.apache.sis.geometries.math.Array;
+
+/**
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class AnimationSampler {
+
+ private Array time;
+ private Array Values;
+
+ public Array getTime() {
+ return time;
+ }
+
+ public void setTime(Array time) {
+ this.time = time;
+ }
+
+ public Array getValues() {
+ return Values;
+ }
+
+ public void setValues(Array Values) {
+ this.Values = Values;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 19 * hash + Objects.hashCode(this.time);
+ hash = 19 * hash + Objects.hashCode(this.Values);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final AnimationSampler other = (AnimationSampler) obj;
+ if (!Objects.equals(this.time, other.time)) {
+ return false;
+ }
+ if (!Objects.equals(this.Values, other.Values)) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/MorphTarget.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/MorphTarget.java
new file mode 100644
index 0000000000..c518829444
--- /dev/null
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/MorphTarget.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.geometries.scene;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Objects;
+import org.apache.sis.geometries.AttributesType;
+import org.apache.sis.geometries.math.Array;
+import org.apache.sis.geometries.math.DataType;
+import org.apache.sis.geometries.math.SampleSystem;
+
+/**
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class MorphTarget implements AttributesType {
+
+ private final LinkedHashMap<String,Array> attributes = new
LinkedHashMap<>();
+
+ /**
+ * Get geometry attributes type.
+ * @return attributes type, never null
+ */
+ public AttributesType getAttributesType() {
+ return this;
+ }
+
+ @Override
+ public List<String> getAttributeNames() {
+ return List.of(attributes.keySet().toArray(new String[0]));
+ }
+
+ @Override
+ public SampleSystem getAttributeSystem(String name){
+ Array att = getAttribute(name);
+ if (att == null) return null;
+ return att.getSampleSystem();
+ }
+
+ @Override
+ public DataType getAttributeType(String name){
+ Array att = getAttribute(name);
+ if (att == null) return null;
+ return att.getDataType();
+ }
+
+ /**
+ * Returns tuple array for given name.
+ *
+ * @param name seached attribute name
+ * @return attribute array or null.
+ */
+ public Array getAttribute(String name) {
+ return attributes.get(name);
+ }
+
+ /**
+ * @param name attribute name
+ * @param array if null, will remove the attribute
+ */
+ public void setAttribute(String name, Array array) {
+ if (array == null) {
+ attributes.remove(name);
+ } else {
+ attributes.put(name, array);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 67 * hash + Objects.hashCode(this.attributes);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final MorphTarget other = (MorphTarget) obj;
+ if (!Objects.equals(this.attributes, other.attributes)) {
+ return false;
+ }
+ return true;
+ }
+
+
+}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/SceneNode.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/SceneNode.java
index 16f8cfb104..e3fcb61437 100644
---
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/SceneNode.java
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/SceneNode.java
@@ -102,6 +102,8 @@ public class SceneNode {
private Model model;
private String name;
private Feature feature;
+ private Skin skin;
+ private final List<Animation> animations = new ArrayList<>();
//user properties
private Map<String,Object> properties;
@@ -241,6 +243,27 @@ public class SceneNode {
this.camera = camera;
}
+ /**
+ * @return skin attached, may be null
+ */
+ public Skin getSkin() {
+ return skin;
+ }
+
+ /**
+ * @param skin model skin to attach, may be null
+ */
+ public void setSkin(Skin skin) {
+ this.skin = skin;
+ }
+
+ /**
+ * @return animations attached to this node
+ */
+ public List<Animation> getAnimations() {
+ return animations;
+ }
+
/**
* @return Feature this node represent
* used to attach atttributes on scene models.
@@ -370,6 +393,12 @@ public class SceneNode {
if (!Objects.equals(this.model, other.model)) {
return false;
}
+ if (!Objects.equals(this.skin, other.skin)) {
+ return false;
+ }
+ if (!Objects.equals(this.animations, other.animations)) {
+ return false;
+ }
return true;
}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Skin.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Skin.java
new file mode 100644
index 0000000000..3fcd1bfe25
--- /dev/null
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Skin.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.geometries.scene;
+
+import java.util.List;
+import java.util.Objects;
+import org.apache.sis.geometries.math.Matrix4D;
+
+/**
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class Skin {
+
+ private List<Matrix4D> ibm;
+ private SceneNode root;
+ private List<SceneNode> joints;
+
+ public List<Matrix4D> getInverseBindMatrices() {
+ return ibm;
+ }
+
+ public void setInverseBindMatrices(List<Matrix4D> ibm) {
+ this.ibm = ibm;
+ }
+
+ public SceneNode getRoot() {
+ return root;
+ }
+
+ public void setRoot(SceneNode root) {
+ this.root = root;
+ }
+
+ public List<SceneNode> getJoints() {
+ return joints;
+ }
+
+ public void setJoints(List<SceneNode> joints) {
+ this.joints = joints;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 97 * hash + Objects.hashCode(this.ibm);
+ hash = 97 * hash + Objects.hashCode(this.root);
+ hash = 97 * hash + Objects.hashCode(this.joints);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Skin other = (Skin) obj;
+ if (!Objects.equals(this.ibm, other.ibm)) {
+ return false;
+ }
+ if (!Objects.equals(this.root, other.root)) {
+ return false;
+ }
+ if (!Objects.equals(this.joints, other.joints)) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
index 9da1dc4543..5abc2506d9 100644
---
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
@@ -16,6 +16,8 @@
*/
package org.apache.sis.geometries.scene;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import org.apache.sis.geometries.Geometry;
import org.apache.sis.util.ArgumentChecks;
@@ -30,6 +32,7 @@ public class Surface {
private Geometry geometry;
private Material material;
+ private final List<MorphTarget> targets = new ArrayList<>();
public Surface(Geometry geometry) {
ArgumentChecks.ensureNonNull("geometry", geometry);
@@ -76,6 +79,13 @@ public class Surface {
this.material = material;
}
+ /**
+ * @return morph targets, list is never nul, can be empty.
+ */
+ public List<MorphTarget> targets() {
+ return targets;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) {
@@ -94,7 +104,7 @@ public class Surface {
if (!Objects.equals(this.material, other.material)) {
return false;
}
- return true;
+ return Objects.equals(this.targets, other.targets);
}
@Override