public static CurveHandle GetCurve(IINode _node, int[] _frames, int _f, int _samplingRate) { CurveHandle result = new CurveHandle(Vector2.Zero, Vector2.Zero); IIGameNode _GNode = maxGlobal.IGameInterface.GetIGameNode(_node); int _ticks_per_frame = maxGlobal.TicksPerFrame; float delta = 0.0f; if (_f > 0) { List <Vector3> _samples = new List <Vector3>(); int nb_of_frames = _frames[_f] - _frames[_f - 1]; for (int i = _frames[_f - 1]; i <= _frames[_f]; i += _samplingRate) { float proportion = 1.0f - ((_frames[_f] - i) / (float)(nb_of_frames)); IGMatrix _node_LGmatrix = _GNode.GetLocalTM(i * _ticks_per_frame); DualQuaternion _node_LDQ = _node_LGmatrix.convertToDQ(Transformation.Rotation); _samples.Add(new Vector3(proportion, Math.Abs(_node_LDQ.RollPitchYaw.X) + Math.Abs(_node_LDQ.RollPitchYaw.Y) + Math.Abs(_node_LDQ.RollPitchYaw.Z), 0)); } List <BezierCurveFitting.BezierPoint> points = BezierCurveFitting.FitCurves.FitCurveBy(BezierCurveFitting.Method.Length, _samples.ToArray(), 0.01f, 2); delta = points[1].point.Y - points[0].point.Y; float val = points[1].foreHandle.Value.X; if (delta != 0) { val = (points[1].point.Y - points[1].foreHandle.Value.Y) / delta; } result.easeIn = new Vector2(points[1].foreHandle.Value.X, val); } else if (_f == 0) { result.easeIn = new Vector2(0.0f, 0.0f); } if (_f < _frames.Length - 1) { List <Vector3> _samples = new List <Vector3>(); int nb_of_frames = _frames[_f + 1] - _frames[_f]; for (int i = _frames[_f]; i <= _frames[_f + 1]; i += _samplingRate) { float proportion = 1.0f - ((_frames[_f + 1] - i) / (float)(nb_of_frames)); IGMatrix _node_LGmatrix = _GNode.GetLocalTM(i * _ticks_per_frame); DualQuaternion _node_LDQ = _node_LGmatrix.convertToDQ(Transformation.Rotation); _samples.Add(new Vector3(proportion, Math.Abs(_node_LDQ.RollPitchYaw.X) + Math.Abs(_node_LDQ.RollPitchYaw.Y) + Math.Abs(_node_LDQ.RollPitchYaw.Z), 0)); } List <BezierCurveFitting.BezierPoint> points = BezierCurveFitting.FitCurves.FitCurveBy(BezierCurveFitting.Method.Length, _samples.ToArray(), 0.01f, 2); delta = points[1].point.Y - points[0].point.Y; float val = points[0].afterHandle.Value.X; if (delta != 0) { val = (points[1].point.Y - points[0].afterHandle.Value.Y) / delta; } result.easeOut = new Vector2(points[0].afterHandle.Value.X, val); } else if (_f == _frames.Length - 1) { result.easeOut = new Vector2(1f, 1f); } return(result); }
public void GenerateScalingAnimation(IIGameNode gameNode, List <BabylonAnimation> animations) { if (gameNode.IGameControl.IsAnimated(IGameControlType.Scale)) { ExportVector3Animation("scaling", animations, key => { var localMatrix = gameNode.GetLocalTM(key); if (float.IsNaN(localMatrix.Determinant)) { RaiseError($"Determinant of {gameNode.Name} of scale animation at {key} localMatrix is NaN "); } var tm_babylon = new BabylonMatrix(); tm_babylon.m = localMatrix.ToArray(); var s_babylon = new BabylonVector3(); var q_babylon = new BabylonQuaternion(); var t_babylon = new BabylonVector3(); tm_babylon.decompose(s_babylon, q_babylon, t_babylon); return(new[] { s_babylon.X, s_babylon.Y, s_babylon.Z }); }); } }
public void GenerateRotationAnimation(IIGameNode gameNode, List <BabylonAnimation> animations, bool force = false) { if (gameNode.IGameControl.IsAnimated(IGameControlType.Rot) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerX) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerY) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerZ) || force) { ExportQuaternionAnimation("rotationQuaternion", animations, key => { var localMatrix = gameNode.GetLocalTM(key); var tm_babylon = new BabylonMatrix(); tm_babylon.m = localMatrix.ToArray(); var s_babylon = new BabylonVector3(); var q_babylon = new BabylonQuaternion(); var t_babylon = new BabylonVector3(); tm_babylon.decompose(s_babylon, q_babylon, t_babylon); // normalize var q = q_babylon; float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W); return(new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length }); }); } }
public void GenerateRotationAnimation(IIGameNode gameNode, List <BabylonAnimation> animations, bool force = false) { if (gameNode.IGameControl.IsAnimated(IGameControlType.Rot) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerX) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerY) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerZ) || (gameNode.IGameObject.IGameType == Autodesk.Max.IGameObject.ObjectTypes.Light && gameNode.IGameObject.AsGameLight().LightTarget != null) || // Light with target are indirectly animated by their target force) { ExportQuaternionAnimation("rotationQuaternion", animations, key => { var localMatrix = gameNode.GetLocalTM(key); var tm_babylon = new BabylonMatrix(); tm_babylon.m = localMatrix.ToArray(); var s_babylon = new BabylonVector3(); var q_babylon = new BabylonQuaternion(); var t_babylon = new BabylonVector3(); tm_babylon.decompose(s_babylon, q_babylon, t_babylon); // normalize var q = q_babylon; float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W); return(new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length }); }); } }
private void exportTransform(BabylonAbstractMesh babylonAbstractMesh, IIGameNode maxGameNode) { // Position / rotation / scaling var localTM = maxGameNode.GetLocalTM(0); var meshTrans = localTM.Translation; var meshRotation = localTM.Rotation; var meshScale = localTM.Scaling; babylonAbstractMesh.position = new[] { meshTrans.X, meshTrans.Y, meshTrans.Z }; var rotationQuaternion = new BabylonQuaternion { X = meshRotation.X, Y = meshRotation.Y, Z = meshRotation.Z, W = -meshRotation.W }; if (ExportQuaternionsInsteadOfEulers) { babylonAbstractMesh.rotationQuaternion = rotationQuaternion.ToArray(); } else { babylonAbstractMesh.rotation = rotationQuaternion.toEulerAngles().ToArray(); } babylonAbstractMesh.scaling = new[] { meshScale.X, meshScale.Y, meshScale.Z }; }
public void GenerateRotationAnimation(IIGameNode gameNode, List <BabylonAnimation> animations, bool force = false) { if (isRotationAnimated(gameNode) || force) { ExportQuaternionAnimation("rotationQuaternion", animations, key => { var localMatrix = gameNode.GetLocalTM(key); if (float.IsNaN(localMatrix.Determinant)) { RaiseError($"Determinant of {gameNode.Name} of rotation animation at {key} localMatrix is NaN "); } var tm_babylon = new BabylonMatrix(); tm_babylon.m = localMatrix.ToArray(); var s_babylon = new BabylonVector3(); var q_babylon = new BabylonQuaternion(); var t_babylon = new BabylonVector3(); tm_babylon.decompose(s_babylon, q_babylon, t_babylon); // normalize var q = q_babylon; float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W); return(new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length }); }); } }
private void exportTransform(BabylonAbstractMesh babylonAbstractMesh, IIGameNode maxGameNode) { // Position / rotation / scaling var localTM = maxGameNode.GetLocalTM(0); // use babylon decomposition, as 3ds max built-in values are no correct var tm_babylon = new BabylonMatrix(); tm_babylon.m = localTM.ToArray(); var s_babylon = new BabylonVector3(); var q_babylon = new BabylonQuaternion(); var t_babylon = new BabylonVector3(); tm_babylon.decompose(s_babylon, q_babylon, t_babylon); if (ExportQuaternionsInsteadOfEulers) { babylonAbstractMesh.rotationQuaternion = q_babylon.ToArray(); } else { babylonAbstractMesh.rotation = q_babylon.toEulerAngles().ToArray(); } // normalize quaternion var q = q_babylon; float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W); babylonAbstractMesh.rotationQuaternion = new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length }; babylonAbstractMesh.scaling = new[] { s_babylon.X, s_babylon.Y, s_babylon.Z }; babylonAbstractMesh.position = new[] { t_babylon.X, t_babylon.Y, t_babylon.Z }; }
public void GeneratePositionAnimation(IIGameNode gameNode, List <BabylonAnimation> animations) { if (isPositionAnimated(gameNode)) { ExportVector3Animation("position", animations, key => { var localMatrix = gameNode.GetLocalTM(key); if (float.IsNaN(localMatrix.Determinant)) { RaiseError($"Determinant of {gameNode.Name} of position animation at {key} localMatrix is NaN "); } var tm_babylon = new BabylonMatrix(); tm_babylon.m = localMatrix.ToArray(); var s_babylon = new BabylonVector3(); var q_babylon = new BabylonQuaternion(); var t_babylon = new BabylonVector3(); tm_babylon.decompose(s_babylon, q_babylon, t_babylon); // Apply unit conversion factor to meter t_babylon *= scaleFactorToMeters; return(new[] { t_babylon.X, t_babylon.Y, t_babylon.Z }); }); } }
public static DualQuaternion GetBoneLocalDQ(IINode _node, int[] _frames, int _f) { IINode _parent_node = _node.ParentNode; IIGameNode _GNode = maxGlobal.IGameInterface.GetIGameNode(_node); IIGameNode _parentGNode = maxGlobal.IGameInterface.GetIGameNode(_parent_node); int _ticks_per_frame = maxGlobal.TicksPerFrame; // node Local Transform IGMatrix _node_LGmatrix = _GNode.GetLocalTM(_frames[_f] * _ticks_per_frame); DualQuaternion _node_LDQ = _node_LGmatrix.convertToDQ(Transformation.Rotation); _node_LDQ.Normalize(); IGMatrix _node_BLGmatrix = _GNode.GetLocalTM(0); DualQuaternion _node_BLDQ = _node_BLGmatrix.convertToDQ(Transformation.Rotation); _node_BLDQ.Normalize(); DualQuaternion _node_LTDQL = _node_LDQ * DualQuaternion.Conjugate(_node_BLDQ); return(_node_LTDQL); }
public void GenerateScalingAnimation(IIGameNode gameNode, List <BabylonAnimation> animations) { if (gameNode.IGameControl.IsAnimated(IGameControlType.Scale)) { ExportVector3Animation("scaling", animations, key => { var localMatrix = gameNode.GetLocalTM(key); var scale = localMatrix.Scaling; return(new[] { scale.X, scale.Y, scale.Z }); }); } }
public void GeneratePositionAnimation(IIGameNode gameNode, List <BabylonAnimation> animations) { if (gameNode.IGameControl.IsAnimated(IGameControlType.Pos) || gameNode.IGameControl.IsAnimated(IGameControlType.PosX) || gameNode.IGameControl.IsAnimated(IGameControlType.PosY) || gameNode.IGameControl.IsAnimated(IGameControlType.PosZ)) { ExportVector3Animation("position", animations, key => { var localMatrix = gameNode.GetLocalTM(key); var trans = localMatrix.Translation; return(new[] { trans.X, trans.Y, trans.Z }); }); } }
public void GenerateRotationAnimation(IIGameNode gameNode, List <BabylonAnimation> animations, bool force = false) { if (gameNode.IGameControl.IsAnimated(IGameControlType.Rot) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerX) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerY) || gameNode.IGameControl.IsAnimated(IGameControlType.EulerZ) || force) { ExportQuaternionAnimation("rotationQuaternion", animations, key => { var localMatrix = gameNode.GetLocalTM(key); var rot = localMatrix.Rotation; return(new[] { rot.X, rot.Y, rot.Z, -rot.W }); }); } }
public void GenerateScalingAnimation(IIGameNode gameNode, List <BabylonAnimation> animations) { if (gameNode.IGameControl.IsAnimated(IGameControlType.Scale)) { ExportVector3Animation("scaling", animations, key => { var localMatrix = gameNode.GetLocalTM(key); var tm_babylon = new BabylonMatrix(); tm_babylon.m = localMatrix.ToArray(); var s_babylon = new BabylonVector3(); var q_babylon = new BabylonQuaternion(); var t_babylon = new BabylonVector3(); tm_babylon.decompose(s_babylon, q_babylon, t_babylon); return(new[] { s_babylon.X, s_babylon.Y, s_babylon.Z }); }); } }
private void ExportCamera(IIGameScene scene, IIGameNode cameraNode, BabylonScene babylonScene) { if (cameraNode.MaxNode.GetBoolProperty("babylonjs_noexport")) { return; } var gameCamera = cameraNode.IGameObject.AsGameCamera(); var maxCamera = gameCamera.MaxObject as ICameraObject; var initialized = gameCamera.InitializeData; var babylonCamera = new BabylonCamera(); RaiseMessage(cameraNode.Name, 1); babylonCamera.name = cameraNode.Name; babylonCamera.id = cameraNode.MaxNode.GetGuid().ToString(); if (cameraNode.NodeParent != null) { babylonCamera.parentId = GetParentID(cameraNode.NodeParent, babylonScene, scene); } babylonCamera.fov = Tools.ConvertFov(maxCamera.GetFOV(0, Tools.Forever)); if (maxCamera.ManualClip == 1) { babylonCamera.minZ = maxCamera.GetClipDist(0, 1, Tools.Forever); babylonCamera.maxZ = maxCamera.GetClipDist(0, 2, Tools.Forever); } else { babylonCamera.minZ = 0.1f; babylonCamera.maxZ = 10000.0f; } if (babylonCamera.minZ == 0.0f) { babylonCamera.minZ = 0.1f; } // Type babylonCamera.type = cameraNode.MaxNode.GetStringProperty("babylonjs_type", "FreeCamera"); // Control babylonCamera.speed = cameraNode.MaxNode.GetFloatProperty("babylonjs_speed", 1.0f); babylonCamera.inertia = cameraNode.MaxNode.GetFloatProperty("babylonjs_inertia", 0.9f); // Collisions babylonCamera.checkCollisions = cameraNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions"); babylonCamera.applyGravity = cameraNode.MaxNode.GetBoolProperty("babylonjs_applygravity"); babylonCamera.ellipsoid = cameraNode.MaxNode.GetVector3Property("babylonjs_ellipsoid"); // Position / rotation var localTM = cameraNode.GetObjectTM(0); if (cameraNode.NodeParent != null) { var parentWorld = cameraNode.NodeParent.GetObjectTM(0); localTM.MultiplyBy(parentWorld.Inverse); } var position = localTM.Translation; var rotation = localTM.Rotation; var exportQuaternions = Loader.Core.RootNode.GetBoolProperty("babylonjs_exportquaternions"); babylonCamera.position = new[] { position.X, position.Y, position.Z }; if (exportQuaternions) { babylonCamera.rotationQuaternion = new[] { rotation.X, rotation.Y, rotation.Z, -rotation.W }; } else { babylonCamera.rotation = QuaternionToEulerAngles(rotation); } // Target var target = gameCamera.CameraTarget; if (target != null) { babylonCamera.lockedTargetId = target.MaxNode.GetGuid().ToString(); } else { var dir = localTM.GetRow(3); babylonCamera.target = new [] { position.X - dir.X, position.Y - dir.Y, position.Z - dir.Z }; } // Animations var animations = new List <BabylonAnimation>(); ExportVector3Animation("position", animations, key => { var tm = cameraNode.GetLocalTM(key); if (cameraNode.NodeParent != null) { var parentWorld = cameraNode.NodeParent.GetObjectTM(key); tm.MultiplyBy(parentWorld.Inverse); } var translation = tm.Translation; return(new [] { translation.X, translation.Y, translation.Z }); }); if (gameCamera.CameraTarget == null) { ExportVector3Animation("target", animations, key => { var tm = cameraNode.GetLocalTM(key); if (cameraNode.NodeParent != null) { var parentWorld = cameraNode.NodeParent.GetObjectTM(key); tm.MultiplyBy(parentWorld.Inverse); } var translation = tm.Translation; var dir = tm.GetRow(3); return(new float[] { translation.X - dir.X, translation.Y - dir.Y, translation.Z - dir.Z }); }); } ExportFloatAnimation("fov", animations, key => new[] { Tools.ConvertFov((gameCamera.MaxObject as ICameraObject).GetFOV(key, Tools.Forever)) }); babylonCamera.animations = animations.ToArray(); if (cameraNode.MaxNode.GetBoolProperty("babylonjs_autoanimate")) { babylonCamera.autoAnimate = true; babylonCamera.autoAnimateFrom = (int)cameraNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from"); babylonCamera.autoAnimateTo = (int)cameraNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to"); babylonCamera.autoAnimateLoop = cameraNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop"); } babylonScene.CamerasList.Add(babylonCamera); }
private void ExportCamera(IIGameScene scene, IIGameNode cameraNode, BabylonScene babylonScene) { if (cameraNode.MaxNode.GetBoolProperty("babylonjs_noexport")) { return; } var gameCamera = cameraNode.IGameObject.AsGameCamera(); var maxCamera = gameCamera.MaxObject as ICameraObject; var initialized = gameCamera.InitializeData; var babylonCamera = new BabylonCamera(); RaiseMessage(cameraNode.Name, 1); babylonCamera.name = cameraNode.Name; babylonCamera.id = cameraNode.MaxNode.GetGuid().ToString(); if (cameraNode.NodeParent != null) { babylonCamera.parentId = GetParentID(cameraNode.NodeParent, babylonScene, scene); } babylonCamera.fov = Tools.ConvertFov(maxCamera.GetFOV(0, Tools.Forever)); if (maxCamera.ManualClip == 1) { babylonCamera.minZ = maxCamera.GetClipDist(0, 1, Tools.Forever); babylonCamera.maxZ = maxCamera.GetClipDist(0, 2, Tools.Forever); } else { babylonCamera.minZ = 0.1f; babylonCamera.maxZ = 10000.0f; } if (babylonCamera.minZ == 0.0f) { babylonCamera.minZ = 0.1f; } // Type babylonCamera.type = cameraNode.MaxNode.GetStringProperty("babylonjs_type", "FreeCamera"); // Control babylonCamera.speed = cameraNode.MaxNode.GetFloatProperty("babylonjs_speed", 1.0f); babylonCamera.inertia = cameraNode.MaxNode.GetFloatProperty("babylonjs_inertia", 0.9f); // Collisions babylonCamera.checkCollisions = cameraNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions"); babylonCamera.applyGravity = cameraNode.MaxNode.GetBoolProperty("babylonjs_applygravity"); babylonCamera.ellipsoid = cameraNode.MaxNode.GetVector3Property("babylonjs_ellipsoid"); // Position var wm = cameraNode.GetLocalTM(0); if (cameraNode.NodeParent != null) { var parentWorld = cameraNode.NodeParent.GetObjectTM(0); wm.MultiplyBy(parentWorld.Inverse); } var position = wm.Translation; babylonCamera.position = new [] { position.X, position.Y, position.Z }; // Target var target = gameCamera.CameraTarget; if (target != null) { babylonCamera.lockedTargetId = target.MaxNode.GetGuid().ToString(); } else { var dir = wm.GetRow(3); babylonCamera.target = new [] { position.X - dir.X, position.Y - dir.Y, position.Z - dir.Z }; } // Animations var animations = new List<BabylonAnimation>(); ExportVector3Animation("position", animations, key => { var tm = cameraNode.GetLocalTM(key); if (cameraNode.NodeParent != null) { var parentWorld = cameraNode.NodeParent.GetObjectTM(key); tm.MultiplyBy(parentWorld.Inverse); } var translation = tm.Translation; return new [] { translation.X, translation.Y, translation.Z }; }); if (gameCamera.CameraTarget == null) { ExportVector3Animation("target", animations, key => { var tm = cameraNode.GetLocalTM(key); if (cameraNode.NodeParent != null) { var parentWorld = cameraNode.NodeParent.GetObjectTM(key); tm.MultiplyBy(parentWorld.Inverse); } var translation = tm.Translation; var dir = tm.GetRow(3); return new float[] { translation.X - dir.X, translation.Y - dir.Y, translation.Z - dir.Z }; }); } ExportFloatAnimation("fov", animations, key => new[] { Tools.ConvertFov((gameCamera.MaxObject as ICameraObject).GetFOV(key, Tools.Forever)) }); babylonCamera.animations = animations.ToArray(); if (cameraNode.MaxNode.GetBoolProperty("babylonjs_autoanimate")) { babylonCamera.autoAnimate = true; babylonCamera.autoAnimateFrom = (int)cameraNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from"); babylonCamera.autoAnimateTo = (int)cameraNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to"); babylonCamera.autoAnimateLoop = cameraNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop"); } babylonScene.CamerasList.Add(babylonCamera); }
private BabylonNode ExportLight(IIGameScene scene, IIGameNode lightNode, BabylonScene babylonScene) { if (IsLightExportable(lightNode) == false) { return(null); } var gameLight = lightNode.IGameObject.AsGameLight(); var initialized = gameLight.InitializeData; var babylonLight = new BabylonLight(); RaiseMessage(lightNode.Name, 1); babylonLight.name = lightNode.Name; // Export the custom attributes of this light babylonLight.metadata = ExportExtraAttributes(lightNode, babylonScene); // To preserve the position/rotation and the hierarchy, we create a dummy that will contains as direct children the light and the light children // The light will have no children. The dummy will contains the position and rotation animations. bool createDummy = lightNode.ChildCount > 0; BabylonNode dummy = null; if (createDummy) { dummy = ExportDummy(scene, lightNode, babylonScene); dummy.name = "_" + dummy.name + "_"; babylonLight.id = Guid.NewGuid().ToString(); babylonLight.parentId = dummy.id; babylonLight.hasDummy = true; } else { babylonLight.id = lightNode.MaxNode.GetGuid().ToString(); if (lightNode.NodeParent != null) { babylonLight.parentId = lightNode.NodeParent.MaxNode.GetGuid().ToString(); } } // Type var maxLight = (lightNode.MaxNode.ObjectRef as ILightObject); var lightState = Loader.Global.LightState.Create(); maxLight.EvalLightState(0, Tools.Forever, lightState); switch (lightState.Type) { case LightType.OmniLgt: babylonLight.type = 0; break; case LightType.SpotLgt: babylonLight.type = 2; babylonLight.angle = (float)(maxLight.GetFallsize(0, Tools.Forever) * Math.PI / 180.0f); babylonLight.exponent = 1; break; case LightType.DirectLgt: babylonLight.type = 1; break; case LightType.AmbientLgt: babylonLight.type = 3; babylonLight.groundColor = new float[] { 0, 0, 0 }; break; } // Shadows if (maxLight.ShadowMethod == 1) { if (lightState.Type == LightType.DirectLgt || lightState.Type == LightType.SpotLgt || lightState.Type == LightType.OmniLgt) { ExportShadowGenerator(lightNode.MaxNode, babylonScene, babylonLight); } else { RaiseWarning("Shadows maps are only supported for point, directional and spot lights", 2); } } // Position / rotation / scaling if (createDummy) { // The position is stored by the dummy parent and the default direction is downward and it is updated by the rotation of the parent dummy babylonLight.position = new[] { 0f, 0f, 0f }; babylonLight.direction = new[] { 0f, -1f, 0f }; } else { exportTransform(babylonLight, lightNode); // Position var localMatrix = lightNode.GetLocalTM(0); var position = localMatrix.Translation; // Direction var target = gameLight.LightTarget; if (target != null) { var targetWm = target.GetObjectTM(0); var targetPosition = targetWm.Translation; var direction = targetPosition.Subtract(position).Normalize; babylonLight.direction = new[] { direction.X, direction.Y, direction.Z }; } else { var vDir = Loader.Global.Point3.Create(0, -1, 0); vDir = localMatrix.ExtractMatrix3().VectorTransform(vDir).Normalize; babylonLight.direction = new[] { vDir.X, vDir.Y, vDir.Z }; } } // The HemisphericLight simulates the ambient environment light, so the passed direction is the light reflection direction, not the incoming direction. // So we need the opposite direction if (babylonLight.type == 3) { var worldRotation = lightNode.GetWorldTM(0).Rotation; BabylonQuaternion quaternion = new BabylonQuaternion(worldRotation.X, worldRotation.Y, worldRotation.Z, worldRotation.W); babylonLight.direction = quaternion.Rotate(new BabylonVector3(0f, 1f, 0f)).ToArray(); } var maxScene = Loader.Core.RootNode; // Exclusion try { var inclusion = maxLight.ExclList.TestFlag(1); //NT_INCLUDE var checkExclusionList = maxLight.ExclList.TestFlag(2); //NT_AFFECT_ILLUM if (checkExclusionList) { var excllist = new List <string>(); var incllist = new List <string>(); foreach (var meshNode in maxScene.NodesListBySuperClass(SClass_ID.Geomobject)) { #if MAX2017 || MAX2018 || MAX2019 || MAX2020 if (meshNode.CastShadows) #else if (meshNode.CastShadows == 1) #endif { var inList = maxLight.ExclList.FindNode(meshNode) != -1; if (inList) { if (inclusion) { incllist.Add(meshNode.GetGuid().ToString()); } else { excllist.Add(meshNode.GetGuid().ToString()); } } } } babylonLight.includedOnlyMeshesIds = incllist.ToArray(); babylonLight.excludedMeshesIds = excllist.ToArray(); } } catch (Exception e) { RaiseMessage("Light exclusion not supported", 2); } // Other fields babylonLight.intensity = maxLight.GetIntensity(0, Tools.Forever); babylonLight.diffuse = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Tools.Forever).ToArray() : new float[] { 0, 0, 0 }; babylonLight.specular = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Tools.Forever).ToArray() : new float[] { 0, 0, 0 }; if (maxLight.UseAtten) { babylonLight.range = maxLight.GetAtten(0, 3, Tools.Forever); } if (exportParameters.exportAnimations) { // Animations var animations = new List <BabylonAnimation>(); if (createDummy) { // Position and rotation animations are stored by the parent (the dummy). The direction result from the parent rotation except for the HemisphericLight. if (babylonLight.type == 3) { BabylonVector3 direction = new BabylonVector3(0, 1, 0); ExportVector3Animation("direction", animations, key => { var worldRotation = lightNode.GetWorldTM(key).Rotation; BabylonQuaternion quaternion = new BabylonQuaternion(worldRotation.X, worldRotation.Y, worldRotation.Z, worldRotation.W); return(quaternion.Rotate(direction).ToArray()); }); } } else { GeneratePositionAnimation(lightNode, animations); ExportVector3Animation("direction", animations, key => { var localMatrixAnimDir = lightNode.GetLocalTM(key); var positionLight = localMatrixAnimDir.Translation; var lightTarget = gameLight.LightTarget; if (lightTarget != null) { var targetWm = lightTarget.GetObjectTM(key); var targetPosition = targetWm.Translation; var direction = targetPosition.Subtract(positionLight).Normalize; return(new[] { direction.X, direction.Y, direction.Z }); } else { var vDir = Loader.Global.Point3.Create(0, -1, 0); vDir = localMatrixAnimDir.ExtractMatrix3().VectorTransform(vDir).Normalize; // The HemisphericLight (type == 3) simulates the ambient environment light, so the passed direction is the light reflection direction, not the incoming direction. // So we need the opposite direction return(babylonLight.type != 3 ? new[] { vDir.X, vDir.Y, vDir.Z } : new[] { -vDir.X, -vDir.Y, -vDir.Z }); } }); // Animation temporary stored for gltf but not exported for babylon // TODO - Will cause an issue when externalizing the glTF export process var extraAnimations = new List <BabylonAnimation>(); // Do not check if node rotation properties are animated GenerateRotationAnimation(lightNode, extraAnimations, true); babylonLight.extraAnimations = extraAnimations; } ExportFloatAnimation("intensity", animations, key => new[] { maxLight.GetIntensity(key, Tools.Forever) }); ExportColor3Animation("diffuse", animations, key => { return(lightState.AffectDiffuse? maxLight.GetRGBColor(key, Tools.Forever).ToArray() : new float[] { 0, 0, 0 }); }); babylonLight.animations = animations.ToArray(); if (lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimate")) { babylonLight.autoAnimate = true; babylonLight.autoAnimateFrom = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from"); babylonLight.autoAnimateTo = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to"); babylonLight.autoAnimateLoop = lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop"); } } babylonScene.LightsList.Add(babylonLight); return(createDummy ? dummy : babylonLight); }
private BabylonLight ExportLight(IIGameScene scene, IIGameNode lightNode, BabylonScene babylonScene) { if (IsLightExportable(lightNode) == false) { return(null); } var gameLight = lightNode.IGameObject.AsGameLight(); var initialized = gameLight.InitializeData; var babylonLight = new BabylonLight(); RaiseMessage(lightNode.Name, 1); babylonLight.name = lightNode.Name; babylonLight.id = lightNode.MaxNode.GetGuid().ToString(); if (lightNode.NodeParent != null) { babylonLight.parentId = lightNode.NodeParent.MaxNode.GetGuid().ToString(); } // Type var maxLight = (lightNode.MaxNode.ObjectRef as ILightObject); var lightState = Loader.Global.LightState.Create(); maxLight.EvalLightState(0, Tools.Forever, lightState); switch (lightState.Type) { case LightType.OmniLgt: babylonLight.type = 0; break; case LightType.SpotLgt: babylonLight.type = 2; babylonLight.angle = (float)(maxLight.GetFallsize(0, Tools.Forever) * Math.PI / 180.0f); babylonLight.exponent = 1; break; case LightType.DirectLgt: babylonLight.type = 1; break; case LightType.AmbientLgt: babylonLight.type = 3; babylonLight.groundColor = new float[] { 0, 0, 0 }; break; } // Shadows if (maxLight.ShadowMethod == 1) { if (lightState.Type == LightType.DirectLgt || lightState.Type == LightType.SpotLgt || lightState.Type == LightType.OmniLgt) { ExportShadowGenerator(lightNode.MaxNode, babylonScene); } else { RaiseWarning("Shadows maps are only supported for point, directional and spot lights", 2); } } // Position var localMatrix = lightNode.GetLocalTM(0); var position = localMatrix.Translation; babylonLight.position = new[] { position.X, position.Y, position.Z }; // Direction var target = gameLight.LightTarget; if (target != null) { var targetWm = target.GetObjectTM(0); var targetPosition = targetWm.Translation; var direction = targetPosition.Subtract(position).Normalize; babylonLight.direction = new[] { direction.X, direction.Y, direction.Z }; } else { var vDir = Loader.Global.Point3.Create(0, -1, 0); vDir = localMatrix.ExtractMatrix3().VectorTransform(vDir).Normalize; babylonLight.direction = new[] { vDir.X, vDir.Y, vDir.Z }; } var maxScene = Loader.Core.RootNode; // Exclusion var inclusion = maxLight.ExclList.TestFlag(1); //NT_INCLUDE var checkExclusionList = maxLight.ExclList.TestFlag(2); //NT_AFFECT_ILLUM if (checkExclusionList) { var excllist = new List <string>(); var incllist = new List <string>(); foreach (var meshNode in maxScene.NodesListBySuperClass(SClass_ID.Geomobject)) { #if MAX2017 || MAX2018 if (meshNode.CastShadows) #else if (meshNode.CastShadows == 1) #endif { var inList = maxLight.ExclList.FindNode(meshNode) != -1; if (inList) { if (inclusion) { incllist.Add(meshNode.GetGuid().ToString()); } else { excllist.Add(meshNode.GetGuid().ToString()); } } } } babylonLight.includedOnlyMeshesIds = incllist.ToArray(); babylonLight.excludedMeshesIds = excllist.ToArray(); } // Other fields babylonLight.intensity = maxLight.GetIntensity(0, Tools.Forever); babylonLight.diffuse = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Tools.Forever).ToArray() : new float[] { 0, 0, 0 }; babylonLight.specular = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Tools.Forever).ToArray() : new float[] { 0, 0, 0 }; if (maxLight.UseAtten) { babylonLight.range = maxLight.GetAtten(0, 3, Tools.Forever); } // Animations var animations = new List <BabylonAnimation>(); GeneratePositionAnimation(lightNode, animations); ExportVector3Animation("direction", animations, key => { var localMatrixAnimDir = lightNode.GetLocalTM(key); var positionLight = localMatrixAnimDir.Translation; var lightTarget = gameLight.LightTarget; if (lightTarget != null) { var targetWm = lightTarget.GetObjectTM(key); var targetPosition = targetWm.Translation; var direction = targetPosition.Subtract(positionLight).Normalize; return(new[] { direction.X, direction.Y, direction.Z }); } else { var vDir = Loader.Global.Point3.Create(0, -1, 0); vDir = localMatrixAnimDir.ExtractMatrix3().VectorTransform(vDir).Normalize; return(new[] { vDir.X, vDir.Y, vDir.Z }); } }); // Animation temporary stored for gltf but not exported for babylon // TODO - Will cause an issue when externalizing the glTF export process var extraAnimations = new List <BabylonAnimation>(); // Do not check if node rotation properties are animated GenerateRotationAnimation(lightNode, extraAnimations, true); babylonLight.extraAnimations = extraAnimations; ExportFloatAnimation("intensity", animations, key => new[] { maxLight.GetIntensity(key, Tools.Forever) }); ExportColor3Animation("diffuse", animations, key => { return(lightState.AffectDiffuse? maxLight.GetRGBColor(key, Tools.Forever).ToArray() : new float[] { 0, 0, 0 }); }); babylonLight.animations = animations.ToArray(); if (lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimate")) { babylonLight.autoAnimate = true; babylonLight.autoAnimateFrom = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from"); babylonLight.autoAnimateTo = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to"); babylonLight.autoAnimateLoop = lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop"); } babylonScene.LightsList.Add(babylonLight); return(babylonLight); }
private BabylonCamera ExportCamera(IIGameScene scene, IIGameNode cameraNode, BabylonScene babylonScene) { if (IsCameraExportable(cameraNode) == false) { return(null); } var gameCamera = cameraNode.IGameObject.AsGameCamera(); var maxCamera = gameCamera.MaxObject as ICameraObject; var initialized = gameCamera.InitializeData; var babylonCamera = new BabylonCamera(); RaiseMessage(cameraNode.Name, 1); babylonCamera.name = cameraNode.Name; babylonCamera.id = cameraNode.MaxNode.GetGuid().ToString(); if (cameraNode.NodeParent != null) { babylonCamera.parentId = cameraNode.NodeParent.MaxNode.GetGuid().ToString(); } babylonCamera.fov = Tools.ConvertFov(maxCamera.GetFOV(0, Tools.Forever)); if (maxCamera.ManualClip == 1) { babylonCamera.minZ = maxCamera.GetClipDist(0, 1, Tools.Forever); babylonCamera.maxZ = maxCamera.GetClipDist(0, 2, Tools.Forever); } else { babylonCamera.minZ = 0.1f; babylonCamera.maxZ = 10000.0f; } if (babylonCamera.minZ == 0.0f) { babylonCamera.minZ = 0.1f; } // Type babylonCamera.type = cameraNode.MaxNode.GetStringProperty("babylonjs_type", "FreeCamera"); // Control babylonCamera.speed = cameraNode.MaxNode.GetFloatProperty("babylonjs_speed", 1.0f); babylonCamera.inertia = cameraNode.MaxNode.GetFloatProperty("babylonjs_inertia", 0.9f); // Collisions babylonCamera.checkCollisions = cameraNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions"); babylonCamera.applyGravity = cameraNode.MaxNode.GetBoolProperty("babylonjs_applygravity"); babylonCamera.ellipsoid = cameraNode.MaxNode.GetVector3Property("babylonjs_ellipsoid"); // Position / rotation var localMatrix = cameraNode.GetLocalTM(0); var position = localMatrix.Translation; var rotation = localMatrix.Rotation; babylonCamera.position = new[] { position.X, position.Y, position.Z }; var rotationQuaternion = new BabylonQuaternion { X = rotation.X, Y = rotation.Y, Z = rotation.Z, W = -rotation.W }; if (ExportQuaternionsInsteadOfEulers) { babylonCamera.rotationQuaternion = rotationQuaternion.ToArray(); } else { babylonCamera.rotation = rotationQuaternion.toEulerAngles().ToArray(); } // Target var target = gameCamera.CameraTarget; if (target != null) { babylonCamera.lockedTargetId = target.MaxNode.GetGuid().ToString(); } else { // TODO - Check if should be local or world var vDir = Loader.Global.Point3.Create(0, -1, 0); vDir = localMatrix.ExtractMatrix3().VectorTransform(vDir).Normalize; vDir = vDir.Add(position); babylonCamera.target = new[] { vDir.X, vDir.Y, vDir.Z }; } // Animations var animations = new List <BabylonAnimation>(); GeneratePositionAnimation(cameraNode, animations); if (target == null) { // Export rotation animation //GenerateRotationAnimation(cameraNode, animations); ExportVector3Animation("target", animations, key => { var localMatrixAnimTarget = cameraNode.GetLocalTM(key); var positionCam = localMatrixAnimTarget.Translation; var vDir = Loader.Global.Point3.Create(0, -1, 0); vDir = localMatrixAnimTarget.ExtractMatrix3().VectorTransform(vDir).Normalize; vDir = vDir.Add(positionCam); return(new[] { vDir.X, vDir.Y, vDir.Z }); }); } // Animation temporary stored for gltf but not exported for babylon // TODO - Will cause an issue when externalizing the glTF export process var extraAnimations = new List <BabylonAnimation>(); // Do not check if node rotation properties are animated GenerateRotationAnimation(cameraNode, extraAnimations, true); babylonCamera.extraAnimations = extraAnimations; ExportFloatAnimation("fov", animations, key => new[] { Tools.ConvertFov((gameCamera.MaxObject as ICameraObject).GetFOV(key, Tools.Forever)) }); babylonCamera.animations = animations.ToArray(); if (cameraNode.MaxNode.GetBoolProperty("babylonjs_autoanimate")) { babylonCamera.autoAnimate = true; babylonCamera.autoAnimateFrom = (int)cameraNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from"); babylonCamera.autoAnimateTo = (int)cameraNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to"); babylonCamera.autoAnimateLoop = cameraNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop"); } babylonScene.CamerasList.Add(babylonCamera); return(babylonCamera); }