Can't access GLTF/GLB submesh nor material info when using (archived) Sceneform 1.16.0 - arcore

Under Sceneform 1.16.0 is not possible to access to submeshes nor materials info present in a GLTF/GLB file, as their count is always zero.
Regarding that this is now an open-source (and archived-abandoned) project by Google, it's possible to inspect the code of Renderable class in order to try to locate where the problem is generated.
This brings us to the constructor:
#SuppressWarnings("initialization")
protected Renderable(Renderable other) {
if (other.getId().isEmpty()) {
throw new AssertionError("Cannot copy uninitialized Renderable.");
}
// Share renderableData with the original Renderable.
renderableData = other.renderableData;
// Copy materials.
Preconditions.checkState(other.materialNames.size() == other.materialBindings.size());
for (int i = 0; i < other.materialBindings.size(); i++) {
Material otherMaterial = other.materialBindings.get(i);
materialBindings.add(otherMaterial.makeCopy());
materialNames.add(other.materialNames.get(i));
}
renderPriority = other.renderPriority;
isShadowCaster = other.isShadowCaster;
isShadowReceiver = other.isShadowReceiver;
// Copy collision shape.
if (other.collisionShape != null) {
collisionShape = other.collisionShape.makeCopy();
}
changeId.update();
}
...where the original Renderable (other) has zero submeshes (other.renderableData) and materials (other.materialBindings).
Any help with this?
Best regards.

Related

How to change transparency of a node?

I'm trying to change transparency of a node. This node has a Renderable attached to it, which is imported from .obj converted to .sfb file. However, nothing seems to be working.
So far, I've tried setting "opacity" property for the material to 0.5, but haven't had much success. Below you can see an example of the code:
this.sceneView.getScene().callOnHierarchy(node -> {
Renderable r = node.getRenderable();
if (r != null) {
for (int i = 0; i < r.getSubmeshCount(); i++) {
Material m = r.getMaterial(i).makeCopy();
m.setFloat("opacity", 0.5f);
r.setMaterial(i, m);
}
}
});

What is the correct way to add different objects (Parcel) at the same position?

I'm trying to add diferent Parcel objects at the same position. My code looks like this, where Rock extends Parcel:
Point origin = null;
Rock rock = null;
for (int i = 0; i < ROCKS; i++) {
if (i % 10 == 0) {
origin = model.getRandomUnoccupiedPosition(sim.getRandomGenerator());
rock = new Rock(origin, destination);
sim.register(rock);
} else {
Rock r = new Rock(origin, destination);
model.addObjectAtSamePosition(r, rock);
}
}
but after a few iterations, I get this error when trying to pick up the Rock with a Vehicle:
Exception in thread "Thread-1" java.lang.IllegalArgumentException: Parcel must be registered and must be either ANNOUNCED or AVAILABE, it is: null. Parcel: [Parcel-103f852].
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:146)
at com.github.rinde.rinsim.core.model.pdp.DefaultPDPModel.pickup(DefaultPDPModel.java:175)
at me.alexrs.mas.roveragent.RoverAgent.tickImpl(RoverAgent.java:105)
at com.github.rinde.rinsim.core.model.pdp.Vehicle.tick(Vehicle.java:55)
at com.github.rinde.rinsim.core.model.time.TimeModel.tickImpl(TimeModel.java:139)
at com.github.rinde.rinsim.core.model.time.SimulatedTimeModel.doStart(SimulatedTimeModel.java:32)
at com.github.rinde.rinsim.core.model.time.TimeModel.start(TimeModel.java:94)
at com.github.rinde.rinsim.ui.SimulationViewer$5.run(SimulationViewer.java:399)
The only Rock that is registered is the one that has been registered in the Simulator, but if I try to register more than one Rock, I get an exception saying that two objects can't be at the same position.

Where is threshold for cluster strategy in openlayers 3?

In openlayers 2.8 there was a threshold associated with the cluster strategy as per ticket https://trac.osgeo.org/openlayers/ticket/1815.
In openlayers 3 there is no mention of it anywhere (and the strategy paradigm seems to be gone as well).
http://openlayers.org/en/master/apidoc/ol.source.Cluster.html
Does anyone know if there exist a ticket for this feature?
The paradigm has changed considerably. In OpenLayers 3 you create a new layer, with a cluster style, and the "threshold" is set as a maxResolution, or minResolution in the layer's options.
Similar to:
var clusterLayer = new ol.layer.Vector({
visible: true,
zIndex: insightMap.totalServcies - element.SortOrder,
id: Id,
serviceId: element.Id,
minResolution: clusteringThreshold,
cluster: true,
});
You can also use minZoom and maxZoom according to the documentaiton, but I've encountered issues with them performing consistently.
Update
It's actually possible to have a proper cluster threshold without recompiling the library. You need to use the geometry of each feature (from the features property of the cluster) in the style function.
const noClusterStyles = [];
vectorLayer.setStyle(feature => {
const features = feature.get('features');
if (features.length > 5) {
return clusterStyle;
} else {
for (let i = 0; ii = features.length; i < ii; ++i) {
const clone = noClusterStyles[i] ? noClusterStyles[i] : noClusterStyle.clone();
clone.setGeometry(features[i].getGeometry());
noClusterStyles[i] = clone;
}
noClusterStyles.length = features.length;
return noClusterStyles;
}
});
Thank you to #ahocevar for the code snippet.
Another solution would require modifying the OL3 library itself.
The ol.source.Cluster.prototype.cluster_ function has the following code snippet :
var neighbors = this.source_.getFeaturesInExtent(extent);
ol.DEBUG && console.assert(neighbors.length >= 1, 'at least one neighbor found');
neighbors = neighbors.filter(function(neighbor) {
var uid = ol.getUid(neighbor).toString();
if (!(uid in clustered)) {
clustered[uid] = true;
return true;
} else {
return false;
}
});
// Add the following
// If one element has more too many neighbors, register it as a cluster of one
// Size-based styling should be handled separately, in the layer style function
let THRESHOLD= 3;
if(neighbors.length > THRESHOLD) {
this.features_.push(this.createCluster_(neighbors));
} else {
for(var j = 0 ; j < neighbors.length ; j++) {
this.features_.push(this.createCluster_([neighbors[j]]));
}
}

Looking for speedups for A* search

I've got the following working A* code in C#:
static bool AStar(
IGraphNode start,
Func<IGraphNode, bool> check,
out List<IGraphNode> path)
{
// Closed list. Hashset because O(1).
var closed =
new HashSet<IGraphNode>();
// Binary heap which accepts multiple equivalent items.
var frontier =
new MultiHeap<IGraphNode>(
(a, b) =>
{ return Math.Sign(a.TotalDistance - b.TotalDistance); }
);
// Some way to know how many multiple equivalent items there are.
var references =
new Dictionary<IGraphNode, int>();
// Some way to know which parent a graph node has.
var parents =
new Dictionary<IGraphNode, IGraphNode>();
// One new graph node in the frontier,
frontier.Insert(start);
// Count the reference.
references[start] = 1;
IGraphNode current = start;
do
{
do
{
frontier.Get(out current);
// If it's in the closed list or
// there's other instances of it in the frontier,
// and there's still nodes left in the frontier,
// then that's not the best node.
} while (
(closed.Contains(current) ||
(--references[current]) > 0) &&
frontier.Count > 0
);
// If we have run out of options,
if (closed.Contains(current) && frontier.Count == 0)
{
// then there's no path.
path = null;
return false;
}
closed.Add(current);
foreach (var edge in current.Edges)
{
// If there's a chance of a better path
// to this node,
if (!closed.Contains(edge.End))
{
int count;
// If the frontier doesn't contain this node,
if (!references.TryGetValue(edge.End, out count) ||
count == 0)
{
// Initialize it and insert it.
edge.End.PathDistance =
current.PathDistance + edge.Distance;
edge.End.EstimatedDistance = CalcDistance(edge.End);
parents[edge.End] = current;
frontier.Insert(edge.End);
references[edge.End] = 1;
}
else
{
// If this path is better than the existing path,
if (current.PathDistance + edge.Distance <
edge.End.PathDistance)
{
// Use this path.
edge.End.PathDistance = current.PathDistance +
edge.Distance;
parents[edge.End] = current;
frontier.Insert(edge.End);
// Keeping track of multiples equivalent items.
++references[edge.End];
}
}
}
}
} while (!check(current) && frontier.Count > 0);
if (check(current))
{
path = new List<IGraphNode>();
path.Add(current);
while (current.PathDistance != 0)
{
current = parents[current];
path.Add(current);
}
path.Reverse();
return true;
}
// Yep, no path.
path = null;
return false;
}
How do I make it faster? No code samples, please; that's a challenge I've set myself.
Edit: To clarify, I'm looking for any advice, suggestions, links, etc. that apply to A* in general. The code is just an example. I asked for no code samples because they make it too easy to implement the technique(s) being described.
Thanks.
Have you looked at this page or this page yet? They have plenty of helpful optimization tips as well as some great information on A* in general.
Change to using a Random Meldable Queue for the heap structure. Since you wanted a programming challenge, I won't show you how I changed the recursive Meld method to not be recursive. That's the trick to getting speed out of that structure. More info in Gambin's paper "Randomized Meldable Priority Queues" (search on the web for that).

How to copy attachments from a List into a document library via workflow activity

I currently have a task list, some of them contain file attachments. As part of a new workflow I'm creating in MOSS Designer I need to copy the attachments to files in a document library. What is the best way to do this? Is there an activity already made for this? Thanks!
I know it is an old question but for someone out there..
private void MoveAppraisalSupportDocs(SPListItemCollection sourceDocsList, SPList destinationDocsLib)
{
int sourceDocCnt = sourceDocsList.Count;
if (sourceDocCnt > 0)
{
for (int sd = 0; sd < sourceDocCnt; sd++)
{
SPListItem sourceItem = sourceDocsList[sd];
byte[] fileBytes = sourceItem.File.OpenBinary();
string destUrl = destinationDocsLib.RootFolder.Url + "/" + sourceItem.File.Name;
SPFile destFile = destinationDocsLib.RootFolder.Files.Add(destUrl, fileBytes, true /*true means overwrite */);
}
}
}

Resources