How to use Material.fromType in Cesium - cesiumjs

I am having trouble using the Cesium.Material.fromType function to create a material using a type and uniforms.
I am referring to the docs here: link
I have the following example I am trying to get to work, however I would like to next use the Dot dynamic type not color. Color seems easier for the moment.
Sandcastle example
This works:
material : Cesium.Color.GREEN
This does not:
material : Cesium.Material.fromType('Color', {
color : new Cesium.Color(1.0, 0.0, 0.0, 1.0)
})
I am getting this error:
Uncaught DeveloperError: Unable to infer material type: [object Object]
It seems like the material property on entities cannot be an object, am I missing a step to convert the material into a primitive type?

So I don't have great news here, but I can at least explain what's wrong. As you know Cesium has two separate API layers, the "Entity" layer (for complex objects like moving vehicles), and the "Primitive" layer (for graphics primitives, like collections of billboards or meshes). What you're doing here is directly constructing a material from the Primitive layer and trying to assign it to an Entity, which will not work.
At the Entity layer, materials are described by a class derived from the abstract base class of MaterialProperty. The derived classes are all Entity-layer classes listed in that doc link, for example there's a ColorMaterialProperty class for solid colors. Being at the entity layer makes these things time-dynamic, so for example your solid color could be blue when the simulation time is at 04:00 and change to red at 06:00, etc. Primitive materials do not have a concept of time baked in and are much lighter-weight as a result.
And now the bad news: There doesn't appear to be a DotMaterialProperty class in Cesium currently. This means the Dot material exists only at the primitive layer API and is not hooked up to the entity layer. The team likes to say "contributions welcome" at this point, and if you were so inclined you could probably get this hooked up by copying either StripeMaterialProperty or GridMaterialProperty and editing it to hook up to Dot.
But in the short term, if you need the Dot material more than you need the Entity layer, you could transition your code over to graphics primitives. You can find sample code for this in the Material Sandcastle Demo under the Procedural Textures drop-down box.

Related

Cloning a viewer material

I want to override the color of a component in the viewer, in order to conserve the same rendering effect than other components I would like to clone an existing material and simply modify the color of the clone.
I can change the color of an existing material as follow:
var renderProxy =
viewer.impl.getRenderProxy(
model, fragIds[0])
renderProxy.material.setHex(0xFF0000)
This affects all other components in the model which are using that material, which is not the desired result.
For that purpose I would like to clone material, modify it and affect the new material to a specific component. Invoking the material.clone() method is working:
var newMat = renderProxy.material.clone()
newMat.setHex(0xFF0000)
But the new material will loose all the specific properties that makes it look nice by the renderer.
So my question "is there a way to -easily- clone a viewer material without writing the cloning code for each property"?
You will need to clone the 'prism' material, rather than the 3js phong-material.
Start with this repo: https://github.com/wallabyway/fusion-chair-configurator
as an example, to create a 'metal' material, use these two lines of code (and copy the initPaint() function).
https://github.com/wallabyway/fusion-chair-configurator/blob/c6d5bd575cdf40194c9fbdd1c5f9bb27c70b356e/docs/js/app.js#L107-L108
The szPrism json string, contains lots of parameters. Prism materials are rather complex, but you can find out more about what these parameters do by understanding this article for the Autodesk Cloud Render ART help page (the real-time renderer built inside Revit2019, Fusion360, etc)...
http://help.autodesk.com/view/ARENDERING/ENU/?guid=GUID-49345267-CE6A-4006-BB58-5BEAFD8B0D0E
Try experimenting with Fusion360's 'render' mode. Start by opening 'appearance' and creating some custom materials. You can modify their parameters in real-time to better understand what they do and get the effect you are looking for.
Here is a tutorial video on Fusion360 custom materials: https://www.youtube.com/watch?v=D9AS5rQhtPo
Let me know if that helps.

Set color of object (Autodesk forge)

This works on model which don't have any color:
this.viewer.setThemingColor(node, red, this.model);
But not on model with objects which have a color.
In the docs you can read:
Highlight an object with a theming color that is blended with the
original object’s material.
Blended? What does it mean? How do I set a color to an object if it already has a color?
P.S:
Typescript typedefinition to the Viewer would really be helpfull.
Update
Think it has something to do with the type of object.
I have run both isolate and setThemingColor (red) on the same items.
In the screenshot below, the red door in lower right corner is selected:
It has a "material" heading.
In this screenshot the door next to it (turquoise) is selected. It's missing the material heading.
Do I need to "apply" material or something to make it change color?
Did you supply a THREE.Vector4 object as color or the second argument? Just dug into the code and it wasn't any type check logic and would lead to your error if the wrong type is given. Also make sure you put in the right model object as the third argument, otherwise the render won't know which model to apply the colors when you have multiple models.
You can details about the usage of this method below:
https://forge.autodesk.com/en/docs/viewer/v6/reference/javascript/viewer3d/#setthemingcolor-dbid-color-model
Edit:
If the component is lacking a material pls see here on how to add a custom one: https://forge.autodesk.com/blog/using-dynamic-texture-inside-custom-shaders
PS: We are working on TypeScript definitions for Viewer and Forge SDK and they could be released soon. Stay tuned!

Corona use object properties from Tiled layers

I am new to Lua scripting, and game development. So please I am just a noob in Lua.
I have searched the net for solutions to my problems, without any luck.
I use Photoshop, Corona, Dusk, json and Tiled on windows7.
I am creating a "board" like game, i.e. Setlers. I am using a world map, as the background. The background image of the game area is a world map (world.png file). I have no problem here.
I would like to create transparrent clickable objects matching the countrys borders on my gamemap with all parameters and values (I have added in Tiled) stored in the object. So When the player clicks on the country the transparrent object (on top of the map) is the one clicked and an eventlistener acts on the click.
In Tiled I can create all the objects I need, naming them + assigning parameters and other values.
If I add object.alpha value in Tiled, the alpha value is passed on to corona and working there.
How can I read these data from the json/tmx file in Corona and adding them to a lua table?
The way I am thinking to use the Tiled map and its objects, is to create one polyline trace of each country’s border (creating one object per country). Then place each “country traced object” on top of the world.png map, also naming the object with the countrys name like “object.name = TileBritannia” and also the other properties for use in game.
My problem is getting the objects info, like object.name, and an eventlistener reacting to a click on the object.
Is a polyline the right way to create a clickable area on a map, when I use a png file as a background image?
What is the best way to create a country border objects, in one layer or with all countries as individual object layers in Tiled.
Can I create one layer with sub objects and still access them in my code?
How do I get the object name and other properties, set in Tiled.
When I try to use the (local britannia = tiledMap:load("britannia.json")) the "load" is not working, getting a nil value.
I am looking for a code that will extract/get/read the object.name i.e. “objBritannia” or "TileBritannia". from the json/tmx file.
When I try to read the different parameters from the json file, I don't get the result I expect. I get the result = function: 046A73B0, was hoping for an object name of some sort.
Please provide links to or code example.
I have edited the question.
Thanks
For questions 1 and 2: I have not used Tiled, but based on Corona Tiled, you have the right strategy in mind. That page makes me think that you can just use tap event listener to detect tap. If you are having issues with the example on that web page, please update your question to be more specific. If tap event handling doesn't work (maybe you're talking about a different Tiled lib), look a Polygon fill and Point in Polygon detection, because that's basically what you need to do. Try some stuff from there. If it still doesn't work for you, then update your question with specifics otherwise it will be likely get closed (it is a little too broad as it is).
For #3, Lua is a dynamic language that supports adding properties to objects in one line. So upon the example on the Corona Tiled page, all you would have to do is
tiledMap = require("tiled")
local britannia = tiledMap:load("britannia.json")
britannia.name = "Britannnia"
local Zulu = tiledMap:load("zulu.json")
zulu.name = "zulu"
Naturally you will probably have a whole bunch so you will create a function that you call for each tile. It's not clear what map.layer["objBritannia "].nameIs("TileBritannia") is supposed to do so I can't comment.

Shadow-casting shaders in Stage3D

I've been working a lot with AGAL vertex and fragment shaders. I've got individual objects lit correctly (including specular shading) but I'd like to have objects cast shadows on OTHER objects. I have looked online, but I think most people working directly with AGAL have built custom Stage3D libraries and the shadow-casting solution doesn't seem to be in the public domain. Anyone willing to change that?
I'd like to know how to get an object to cast a shadow on another. I can't post what I've tried, because I can't get my head around where to begin on this problem. How would you pass the information (whether other objects are blocking the light) into another object's shader?
Thanks.
IT's called Deferred shading, you have to do 2 pass of vertex and fragment shaders.
In the first pass you accumulate informations about distances, normals, occlusion...
In the second pass you render and apply the informations of the first pass to make shadows.
Another options is ShadowMapping:
Basic shadowmap
The basic shadowmap algorithm consists in two passes. First, the scene is rendered from the point of view of the light. Only the depth of each fragment is computed. Next, the scene is rendered as usual, but with an extra test to see it the current fragment is in the shadow.
The “being in the shadow” test is actually quite simple. If the current sample is further from the light than the shadowmap at the same point, this means that the scene contains an object that is closer to the light. In other words, the current fragment is in the shadow.

Triangle edges in CanvasRenderer

I am a newbie regarding three.js and I have a problem with imported geometry (js-file from 3dsmax inclusive all material and textures) and the CanvasRenderer. The CanvasRenderer displays the triangle edges of imported geometry, the WebGLRenderer works well.
Canvas example:
http://der-n.square7.ch/threejs/examples/teapot_canvas.html
WebGL example:
http://der-n.square7.ch/threejs/examples/teapot_webgl.html
In the three.js library I have found the option "overdraw: true" for a material to fix this behaviour but obviously the material+textures are defined by the above mentioned exported 3dsmax js-file.
For the tests I use the "misc_camera_trackball" example with small changes (I have added a JSONLoader, changed some camera and trackball parameters, changed some light colors, added a CanvasRenderer)
Any hints how to solve this?
Thanks for your help.
Best regards
Oggy
In the loader callback, you have all of the loaded materials in an array geometry.materials. You could loop over those materials and set the overdraw property to true for each.
As far as I know, THREE.MeshFaceMaterial is just a pass-through material that indicates "faces have an index that points to a material instance to use from the geometry's materials array", so setting properties for MeshFaceMaterial won't have any effect.