sabresaurus / sabrecsg Goto Github PK
View Code? Open in Web Editor NEWLevel design tools for Unity
License: MIT License
Level design tools for Unity
License: MIT License
Unity added 2D tilemaps in version 2017.2. When you have a tilemap in your scene, it displays a little popup in the bottom left corner. This popup allows you to view the tilemap in isolation from the rest of the scene so it's not obstructed by any other elements.
Anyway, the Tilemap popup often ends up on top of the Sabre UI:
When this happens, I can't click on anything in Sabre. It's not just the area under the tilemap popup that's affected; nothing works, not even the tabs in the top right. The presence of the tilemap popup appears to block all mouse events to the UI layers below it.
There's a workaround for this: deselect your applied brush and select it again. When you do that, it puts the Sabre UI back on top, allowing you to interact with it. But as soon as you deselect your brush, the tilemap popup gets back on top.
I am probably going to be adding some automatic naming:
Cube Brush
Cylinder Brush
Shape Editor Brush
As long as you don't modify them I want them to appear more obviously than:
AppliedBrush
AppliedBrush (1)
AppliedBrush
AppliedBrush (1)
AppliedBrush (2)
It would even be possible to have blue/red/purple preview icons of the type in the hierarchy instead of just the + - and square. What do you think?
I would like to see an example how I can change material with my own script. I'm thinking of creating some predefined "blocks" and then randomly changing the material to some existing material that I have given in a list.
And I want to decide which faces I will replace with the new material.
Does someone have some experience of doing such a thing with SabreCSG? Thanks.
Similar to #8, I'm receiving a ton of errors when placing halved cylinders of different sizes in subtract mod next to each other.
Polygon splitting has resulted in two zero area polygons. This is unhandled.
UnityEngine.Debug:LogError(Object)
Sabresaurus.SabreCSG.PolygonFactory:SplitCoplanarPolygonsByPlane(List`1, Plane, List`1&, List`1&) (at Assets/SabreCSG/Scripts/Core/PolygonFactory.cs:200)
Sabresaurus.SabreCSG.TriangulationNode:.ctor(List`1, List`1) (at Assets/SabreCSG/Scripts/Core/BuildEngine/TriangulationNode.cs:24)
Sabresaurus.SabreCSG.TriangulationNode:.ctor(List`1, List`1) (at Assets/SabreCSG/Scripts/Core/BuildEngine/TriangulationNode.cs:53)
Sabresaurus.SabreCSG.TriangulationNode:.ctor(List`1, List`1) (at Assets/SabreCSG/Scripts/Core/BuildEngine/TriangulationNode.cs:53)
Sabresaurus.SabreCSG.TriangulationNode:.ctor(List`1, List`1) (at Assets/SabreCSG/Scripts/Core/BuildEngine/TriangulationNode.cs:53)
Sabresaurus.SabreCSG.TriangulationNode:.ctor(List`1, List`1) (at Assets/SabreCSG/Scripts/Core/BuildEngine/TriangulationNode.cs:53)
Sabresaurus.SabreCSG.TriangulationNode:.ctor(List`1, List`1) (at Assets/SabreCSG/Scripts/Core/BuildEngine/TriangulationNode.cs:53)
Sabresaurus.SabreCSG.TriangulationNode:.ctor(List`1, List`1) (at Assets/SabreCSG/Scripts/Core/BuildEngine/TriangulationNode.cs:52)
Sabresaurus.SabreCSG.Optimizer:CalculateConvexHulls(List`1) (at Assets/SabreCSG/Scripts/Core/BuildEngine/Optimizer.cs:196)
Sabresaurus.SabreCSG.BrushCache:OptimizeCollision(BrushCache) (at Assets/SabreCSG/Scripts/Core/BuildEngine/BrushCache.cs:554)
Sabresaurus.SabreCSG.CSGFactory:CoreBuild(Object) (at Assets/SabreCSG/Scripts/Core/BuildEngine/CSGFactory.cs:430)
Sabresaurus.SabreCSG.CSGFactory:Build(List`1, CSGBuildSettings, BuildContext, Transform, MaterialMeshDictionary, List`1, Boolean, Boolean, Action`1, Action`2, Action`2, Boolean) (at Assets/SabreCSG/Scripts/Core/BuildEngine/CSGFactory.cs:100)
Sabresaurus.SabreCSG.CSGModelBase:Build(Boolean, Boolean) (at Assets/SabreCSG/Scripts/CSGModelBase.cs:196)
Sabresaurus.SabreCSG.CSGModel:Build(Boolean, Boolean) (at Assets/SabreCSG/Scripts/CSGModel.cs:213)
Sabresaurus.SabreCSG.CSGModel:OnEditorUpdate() (at Assets/SabreCSG/Scripts/CSGModel.cs:1180)
UnityEditor.EditorApplication:Internal_CallUpdateFunctions()
This also results in the CSG model's performance dropping drastically when using Auto Rebuild
. I'm assuming I'm messing up, but I'm new to Unity and can't figure out what I'm doing wrong 😒
When you have a brush selected because you edited something, start playing the game, stop playing the game, edit mode is gone until you select another brush or alike. It's annoying and should be easy to fix.
We have Constructive Solid Geometry and that's incredible, but is SabreCSG limited to just being a CSG tool or can it develop further and provide more level design tools?
For example, what if we introduce SabreCSG Voxel Inside® with a voxel engine alongside CSG? You could combine both to create an even more powerful tool. YuME - Yuponic Map Editor uses small tile prefabs instead of just cubes to easily create detailed worlds. We could transform CSG models into one or more voxels allowing you to rapidly create new tiles without ever leaving the editor (and/or have a dedicated 3D Shape Editor).
As we tend to stay on the grid with CSG brushes, voxels would nearly always align perfectly and there are ways to have multiple grids and voxel sizes to cover all cases. I would love to hear some opinions.
This is perhaps only apparent to users on weak setups (like mine), but having the grid enabled is noticeably taxing. This problem is exacerbated when decreasing the grid scale.
I don't know how badly this would break things, but would it be possible to handle the grid rendering with a shader?
I have never tried using the Runtime CSG library before but one thing that always seemed odd is that we made all of the compound brush variables private like this:
[SerializeField]
float stepDepth = 0.2f;
[SerializeField]
float stepHeight = 0.1f;
[SerializeField]
float stepDepthSpacing = 0f;
[SerializeField]
float stepHeightSpacing = 0f;
...
Doesn't that make it extremely difficult if not nearly impossible to use compound brushes?
Should we make them public or add properties for them?
Curved brushes are incredibly difficult to UV map seamlessly with the surface tools currently available in SabreCSG. AutoUV can't generate satisfying UVs. It would be nice to have a UV editor window that can deal with these types of scenarios or introduce another AutoUV that can handle curvature better.
Edit: Research Notes
I'm stuck at trying to get a reference to the generated GameObject in Start()
I've got several CSG objects in the scene and I want to keep autobuild switched on. I can't get the mesh by name as it's always called "MeshGroup". I can't find a method or property that returns the generated mesh. Do I need to use events/callbacks or am I missing something obvious?
On a new project using unity 5.6.0f3 import SabreCSG, you will get a ton of error like this one bellow:
Assets/SabreCSG/Scripts/Tools/ResizeEditor.cs(1539,55): error CS0103: The name `targetBrushBases' does not exist in the current context
Hi.
I put the SabreCSG-master zip file content into assets folder and i am getting following errors. There is no sabrecsg object in the GameObject menu. I tested with Unity 5.6.5f1 and 2017.1.2f1.
Assets/SabreCSG-master/Scripts/Brushes/CompoundBrushes/Editor/ShapeEditorWindow.cs(990,49): error CS0117: UnityEngine.Screen' does not contain a definition for
safeArea'
Assets/SabreCSG-master/Scripts/Brushes/CompoundBrushes/Editor/ShapeEditorWindow.cs(990,113): error CS0117: UnityEngine.Screen' does not contain a definition for
safeArea'
Assets/SabreCSG-master/Scripts/Brushes/CompoundBrushes/Editor/ShapeEditorWindow.cs(1350,40): error CS0117: UnityEngine.Screen' does not contain a definition for
safeArea'
Assets/SabreCSG-master/Scripts/Brushes/CompoundBrushes/Editor/ShapeEditorWindow.cs(1480,47): error CS0117: UnityEngine.Screen' does not contain a definition for
safeArea'
Assets/SabreCSG-master/Scripts/Brushes/CompoundBrushes/Editor/ShapeEditorWindow.cs(1480,131): error CS0117: UnityEngine.Screen' does not contain a definition for
safeArea'
I'm trying to import a level from another engine that uses CSG. The imported brushes are scaled, rotated and pivoted to oblivion (including root CSGModel). Support for this would be fantastic.
If you wish to contribute a SabreCSG 2D Shape Editor Tutorial please do so and post a link to the YouTube video in this issue! We will feature it in the wiki in several places for all to see.
Here are some suggestions that could be covered in the tutorial:
This is just a suggestion, feel free to do what you think is best. If you wish to make a small series, go ahead. As we sadly don't get paid I don't have the right to tell you what to do anyway.
You can use this wiki page for more information.
To anyone interested, thank you so much, I can't wait to see what you come up with! :)
If you have any questions please feel free to ask me here.
When you reload scripts while in edit mode the blue and orange faces disappear and you are left with a very clear wire-frame that makes it much easier to see what you are doing. I personally prefer this over the current system:
In my opinion this should at least be a checkbox in the preferences window.
Hi all, I'm new to sabreCSG but it's clearly the tool for outputting rock-solid CSG operations. I've been playing around and I'll definitely be using it to create a randomly generated map in my game. I've written 2D CSG in the past and would love to help with SabreCSG's development, but I've never contributed to any open-source projects before. If anyone could point me in the right direction that'd be appreciated. For now I could help produce examples for the experimental API until I'm more familiar. I'm working on something that I'd be happy to submit as an example but I don't see the other two in the branch.
Also Is it possible to render subtraction brushes (or any brushes) while paused? It seems the AppliedBrush objects still exist after calling build, but you can't see the mesh or shape they represent at all. Enabling/disabling components on the right is prohibited. I have no experience scripting for the unity editor or I'd take a look at it myself.
OFten when I use csg I will get holes in the face of a model, while I can't explain the problem I do have examples such as this wall:
But more often than not I'll get this problem from using the subtraction brush to hollow out a cylinder
Here's the error message I get with the cylinder example
Zero normal found, this leads to invalid polyhedron-point tests UnityEngine.Debug:LogError(Object) Sabresaurus.SabreCSG.PolygonFactory:ConstructPolygon(List
1, Boolean) (at Assets/SabreCSG-master/Scripts/Core/PolygonFactory.cs:331)
Sabresaurus.SabreCSG.PolygonFactory:SplitPolygonsByPlane(List1, Plane, Boolean, List
1&, List1&) (at Assets/SabreCSG-master/Scripts/Core/PolygonFactory.cs:113) Sabresaurus.SabreCSG.BrushChunk:SplitByPlane(Plane, BrushChunk&, BrushChunk&) (at Assets/SabreCSG-master/Scripts/Core/CSG/BrushChunk.cs:272) Sabresaurus.SabreCSG.BrushBuilder:SplitAndRemove(LinkedList
1, BrushCache, Int32[]) (at Assets/SabreCSG-master/Scripts/Core/BuildEngine/BrushBuilder.cs:465)
Sabresaurus.SabreCSG.BrushBuilder:Build(BrushCache, Int32, BrushCache[], Boolean) (at Assets/SabreCSG-master/Scripts/Core/BuildEngine/BrushBuilder.cs:55)
Sabresaurus.SabreCSG.CSGFactory:CoreBuild(Object) (at Assets/SabreCSG-master/Scripts/Core/BuildEngine/CSGFactory.cs:266)
Sabresaurus.SabreCSG.CSGFactory:Build(List1, CSGBuildSettings, BuildContext, Transform, MaterialMeshDictionary, List
1, Boolean, Boolean, Action1, Action
2, Action2, Boolean) (at Assets/SabreCSG-master/Scripts/Core/BuildEngine/CSGFactory.cs:100) Sabresaurus.SabreCSG.CSGModelBase:Build(Boolean, Boolean) (at Assets/SabreCSG-master/Scripts/CSGModelBase.cs:196) Sabresaurus.SabreCSG.CSGModel:Build(Boolean, Boolean) (at Assets/SabreCSG-master/Scripts/CSGModel.cs:213) Sabresaurus.SabreCSG.Toolbar:OnBottomToolbarGUI(Int32) (at Assets/SabreCSG-master/Scripts/UI/Toolbar.cs:295) UnityEditor.DockArea:OnGUI()
I have some thoughts on how extrusion behavior is currently implemented. I hope they make sense! If not, tell me and I'll try to clarify.
First off, drawing on surfaces generally works quite well, but I think there's room for improvement:
Couple of words on extruding faces:
...would be astonishing.
However I'm sure it's not trivial. I thought it would be worth leaving this here as a placeholder as I'm not going to be the only person dreaming of level design with a headset on.
I'm going to wait for a few more examples of custom additions to EditorXR to surface to see how complex it is to add in support. So far I've only found two (neither of which are actively being updated):
https://github.com/ajcampbell1333/unity3d-editorvr-hierarchymode
First off, this issue only occurs when the user is being a bit daft. However, it still may happen in the rush of editing and could ruin an entire CSG model.
This is how I've been re-created the problem. Draw a shape on a surface without extruding it.
Draw another shape overlapping the first one.
Extrude.
The extruded shape isn't converted to level geometry. The following error message pops up:
"Polygon splutting has resulted in two zero area polygons. This is unhandled. UnityEngine.Debug:LogError(Object)"
Realizing one has made a mistake, the natural inclination is to undo the action. This causes the entire CSG model to lose it's level geometry. From this point it's no longer possible to select any of the brushes in the hierarchy.
Re-doing doesn't help.
The only fix I've discovered is to remove the conflicting shape(s) and move the remaining brushes to a new CSG model.
When you create a new group brush by pressing G and then use the bounds tool the group will jump to 0,0,0. After this occurs once, the group will work as expected from there on out. You can undo the jump. This happens because the bounds are unknown at the creation of the group brush (Awake()) but are set once invalidated for the first time. The code that prevents resizing the group on invalidate will mess up and jump to 0,0,0.
I know there's a code API to make levels at runtime, but I suck at making things like handles for vertices, etc.
I'd like to request a 1:1 equivalent of SabreCSG tools that work at runtime (without Unity). My reasoning is that I want to add extensive level editing to my game. Thing that I have now works, but it isn't too good. I want players to make levels without the need to fight with assetbundles and so on, directly in the game. Therefore, runtime version of SabreCSG would greatly help achieve this.
Ability to serialize/deserialize resulting level data into arrays of basic types, so they can be then stored as part of custom binary data format I've developed for my game would be welcome.
Note that I am unable to do such port myself, otherwise I'd be doing it right now instead of talking.
Heres a 30second video showing the problem (its easy for me to reproduce)
http://somup.com/cFe2fpVBu1
( its unlisted so anyone who has the link can see it but it won't be in the youtube search results)
Briefly summarizing the video: When I do the "extrude face" function it works on default cubes, but trying to extrude face on a shape made by the 2d shape editor has a problem: the extruded face is placed near the origin and not on the original face where it should be.
The problem seems to only happens if the Shape Editor Brush is not located at 0,0,0
Heres another video showing me narrowing down the problem space
http://somup.com/cFe2f8VBui
How can I help?
Clicking on a face, make it´s texture distorted and shows the error:
IndexOutOfRangeException: Array index is out of range.
Sabresaurus.SabreCSG.SurfaceEditor.TransformUVs (Sabresaurus.SabreCSG.Polygon polygon, Sabresaurus.SabreCSG.UVTransformation transformationMethod, Sabresaurus.SabreCSG.TransformData transformData, Boolean recordUndo) (at Assets/SabreCSG-master/Scripts/Tools/SurfaceEditor.cs:1037)
Sabresaurus.SabreCSG.SurfaceEditor.TransformUVs (Sabresaurus.SabreCSG.UVTransformation transformationMethod, Sabresaurus.SabreCSG.TransformData transformData, Boolean recordUndo) (at Assets/SabreCSG-master/Scripts/Tools/SurfaceEditor.cs:985)
Sabresaurus.SabreCSG.SurfaceEditor.OnMouseDragTranslate (UnityEditor.SceneView sceneView, UnityEngine.Event e) (at Assets/SabreCSG-master/Scripts/Tools/SurfaceEditor.cs:391)
Sabresaurus.SabreCSG.SurfaceEditor.OnMouseDrag (UnityEditor.SceneView sceneView, UnityEngine.Event e) (at Assets/SabreCSG-master/Scripts/Tools/SurfaceEditor.cs:280)
Sabresaurus.SabreCSG.SurfaceEditor.OnSceneGUI (UnityEditor.SceneView sceneView, UnityEngine.Event e) (at Assets/SabreCSG-master/Scripts/Tools/SurfaceEditor.cs:108)
Sabresaurus.SabreCSG.CSGModel.OnSceneGUI (UnityEditor.SceneView sceneView) (at Assets/SabreCSG-master/Scripts/CSGModel.cs:506)
UnityEditor.SceneView.CallOnSceneGUI () (at C:/buildslave/unity/build/Editor/Mono/SceneView/SceneView.cs:2075)
UnityEditor.SceneView.HandleSelectionAndOnSceneGUI () (at C:/buildslave/unity/build/Editor/Mono/SceneView/SceneView.cs:1405)
UnityEditor.SceneView.OnGUI () (at C:/buildslave/unity/build/Editor/Mono/SceneView/SceneView.cs:1242)
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
So I just downloaded SabreCSG like half an hour ago and started playing around. It's been many years since I've used a level editor so it's kind of fun to relearn it.
Anyway I came across an odd issue, this is a screenshot of some mesh in a 'doorway'.
The black triangle is caused by overlapping faces from what I can surmise. This is the wireframe
The wall/corridor intersect is crated by having a large box with 2 smaller boxes. This is the entire end wall in wireframe
I was very confused by the circular wireframe until it struck me that it may be defined by a brush that's no where near it, and that turned out to be true.
In the following screenshot I've moved the camera back even further so it's as sort looking into the room it was inside before.
As you can see the circular wireframe makes sense for this doorway but for some reason the same structure is repeated on the next wall.
To clarify, I'm hollowing out a large cube to create an interior scene, this may be why it's acting out..?
Cause the same pattern is repeated on the wall at the very front of the cube as well even though that's it's even further away from the cyllindrical remove brush.
I'd be happy to upload the scene too if that's necessary.
There is a bug between SabreCSG and Unity with its continuous building of lighting, when this is switched off (as SabreCSG does when you create a CSG Model to prevent small edits causing rebakes all the time) then the lighting comes in too dark for some reason on reloading the scene, this is an issue outside of SabreCSG (e.g. see this thread and this thread)
You can turn "auto generate" back on in the lighting window which may be okay depending on your level/lighting set up, or alternatively hit the Generate Lighting button on a scene load.
In the second link helgewl mentions a solution which could help and remove the need for SabreCSG to turn off auto lighting
Alternatively we could cache the state of auto lighting when the user turns on Auto Rebuild, turn it off, then restore it when SabreCSG or Auto Rebuild is disabled
By default a primitive brush builder will retain its bounds while changing the settings. That was a problem with my curved staircases as it changes dimensions like crazy and if it keeps the original bounds it will just get squashed and it's a mess. PrimitiveBrushInspector/ResetPolygonsKeepScale():92
Now I just reset the brush and apply the new geometry, that's great, but every time you move the curved staircase around with the bounds tool and change the settings again it will move around in unexpected ways. I think it may be resetting the pivot position but I am not entirely sure.
Can you give me some advice on how to fix this behavior? PrimitiveBrushInspector/ResetPolygons():82
This is no reason to ignore the pull request, it's just annoying to the end user when you make edits later and it keeps flying away from you slightly and you have to align it again.
My desired end-result would be freezing the translation in place. So it would become ResetPolygonsKeepTranslation().
Assets/SabreCSG-master/Scripts/Core/CSG/Polygon.cs(168,36): error CS0029: Cannot implicitly convert type `void' to `UnityEngine.Plane?'
I'd guess that:
cachedPlane = cachedPlane.Value.Flip();
could just be:
cachedPlane.Value.Flip();
It would allow more control over the size of each segment & overall curve of the final result. I quickly slapped in a field to demonstrate, see here:
https://streamable.com/n5vyt
I often exclude faces for visibility purposes when editing, but this affects the lighting in some cases. Would it be possible to add an option to hide rather than exclude faces, allowing them to still create shadows? (Apologies if I've missed something obvious)
It's possible to group brushes by creating an empty GameObject and inserting the brushes as children. Could this be handled automatically? E.g. select the brushes you wish to group, press Ctrl+G and a parent GameObject is created.
Also, it would be convenient if selecting a parent GameOject selected all the children. And/or, if there was a option to select the entire group when clicking a child. Is this feasible? Perhaps it would make more sense to group brushes using some specific Sabre CSG object instead.
Due to an ongoing discussion on Twitter and a quick proof of concept:
This proof of concept only uses a single concave brush.
I am considering to actually go ahead and add displacement / terrain to SabreCSG.
Because I am using a single concave brush the CSG algorithm can't process it properly (although it does work well if a subtractive brush goes through the brush completely but it's better to use NoCSG). Optimize Geometry breaks the surface but I think it may be possible to exclude the brush from the optimization process (edit: confirmed, this is easy to do).
It may also be possible to, similar to the 2D Shape Editor, have multiple small convex brushes so that you are able to subtract it- or from it for special level design cases. Just to have the option.
I've been looking around, but can't find anything on the topic.
I need to be able to store a SabreCSG model to be loaded in at runtime (level instansing and such).
I know there is a way to build the geometry built in SabreCSG into a .obj file, however this strips away any textures previously applied to the model.
I have tried to create a prefab with the SabreCSG model in it, but whenever I pull it into a scene the model needs to be re-built. This is an issue since there is no run-time brush-building from what I've gathered. It also breaks any prefab instance, meaning that if I later update the prefab it will not reflect in the scene. Is there a way for us to be able to persist the full SabreCSG model including textures other than keeping it stored in a scene and loading that in?
Thanks!
If you have a "Cube Brush (2 x 2 x 2)" and duplicate it, the duplicate will not update its name anymore when you resize it.
You often get this very ugly matte shine:
The problem is the reflection probe, making the reflection probe black will cause all metals to be black which is not what you want, in the "MaterialMesh" settings you can disable reflection probes:
To get the result you'd want:
But SabreCSG forgets this setting after every rebuild. Perhaps this should be the default- or have a checkbox in the CSG Model settings that's like:
Common Fixes
[ ] The world is shiny and weird
As I am not sure everyone will immediately realize it's the reflection probe causing this, like me, and even exposing the reflection probe settings in the CSG Model may then not help anyone figure it out at first.
Attempting to vertex snap a compound brush or a group (in translate mode, holding V) will cause thousands of errors in the console and doesn't work.
Hey this is a bit of a question / Request.
Would it be possible to get the version of Unity that SabreCSG is compatible with listed at the top of the readme?
What version of Unity is SabreCSG compatible with?
Thank you for your time,
HeadClot
More of a question about the viability rather than a feature request. Is it possible to port the editing tools to work at runtime? Probably with some prefab to place in a scene that handles the editing controls.
I'm happy to try and build this myself, but was wondering if there were any immediate gotchas or issues that would make it too impractical.
Would this be possible to implement? It's something I used often with Valve's Hammer Editor, it can be really useful at times.
I have been encountering this issue every time I create a dark environment. The triangulation seams are all slightly separated (I guess?) allowing very thin dynamic light to shine through as well as the skybox to be seen through thousands of flashing bright pixels.
I made a script that causes the player to "breathe" by slightly moving the camera up and down over time, it makes this extremely noticeable. I am actually looking into this problem myself I just figured I should start a discussion here as it may require the author's CSG knowledge to figure this out. ;)
Extrude to a 2D Shape Editor Brush.
Press CTRL+Z.
Will not behave as expected.
From the discussion in #58.
I have this L-shaped brush. As you can see, I created it by subtracting one brush with another. I've grouped the two brushes and I'd like to be able to treat them as a single brush.
In this case I'd like to use this particular group to subtract L-shaped holes in a wall - in other words, I'd like to be able to set the group to subtract, I guess essentially "inverting" the childrens' current mode (while hiding this from the user!).
Great addon! I've been using it for a bit, but ran into something today that caused a lot of head scratching until I finally figured out what I had done wrong. Every time I grabbed a few brushes to move them with the resize bounds tool, they moved both faces on the edited axis to an unexpected position.
If non-one scale is not supported, then could just display a warning to user when they attempt to set a non-one scale and reset it back to a proper value.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.