/// <summary> /// Converts a global mappos to a local under a roi /// </summary> /// <param name="result"></param> /// <returns></returns> public bool ToLocal(MapPos result) { if (result.node != null) // Already local { return(true); } if (_topRoi == null) { return(false); } RoiNode roi = _topRoi.GetClosestRoiNode(result.position); result.node = roi; // Remove roiNode position as offset - Go to local RoiNode based coordinate system if (roi != null && roi.IsValid()) { result.position -= roi.Position; return(true); } return(false); // We failed to convert }
public bool GetGroundPosition(Vec3D position, Vec3 direction, out MapPos result, ClampFlags flags = ClampFlags.DEFAULT) { result = new MapPos(); // Coordinate is now in world Cartesian coordinates (Roi Position) Vec3D origo = new Vec3D(0, 0, 0); // Set used origo Intersector isect = new Intersector(); // Check camera frustrum ----------------------------------------------------------- if (_camera != null && _camera.IsValid()) { origo = _camera.Position; if ((flags & ClampFlags.FRUSTRUM_CULL) != 0) { isect.SetCamera(_camera); } } // Adjust intersector to use origo as center position = position - origo; isect.SetStartPosition((Vec3)position); isect.SetDirection(direction); if (isect.Intersect(_currentMap, IntersectQuery.NEAREST_POINT | IntersectQuery.NORMAL | ((flags & ClampFlags.WAIT_FOR_DATA) != 0 ? IntersectQuery.WAIT_FOR_DYNAMIC_DATA : 0), 1, true, origo)) { IntersectorResult res = isect.GetResult(); IntersectorData data = res.GetData(0); result.position = data.position + origo; result.normal = data.normal; result.clamped = true; } isect.Dispose(); // Drop handle and ignore GC if (_topRoi != null) { RoiNode roi = _topRoi.GetClosestRoiNode(result.position); result.node = roi; // Remove roiNode position as offset - Go to local RoiNode based coordinate system if (roi != null && roi.IsValid()) { result.position -= roi.Position; } } return(true); }
public RoiNode GetClosestRoiNode(Vec3D position) { //NodeLock.WaitLockEdit(); RoiNode node = CreateObject(Roi_getClosestRoiNode(GetNativeReference(), ref position)) as RoiNode; //NodeLock.UnLock(); return(node); }
public Vec3D LocalToWorld(MapPos mappos) { Vec3D result = mappos.position; RoiNode roi = mappos.node as RoiNode; if (roi != null && roi.IsValid()) { result += roi.Position; } return(new Vec3D(result.x, result.y, -result.z)); }
public bool LocalToWorld(MapPos pos, out CartPos result) { Vec3D position = pos.position; RoiNode roi = pos.node as RoiNode; if (roi != null && roi.IsValid()) // Convert to a global position { position += roi.Position; } return(GlobalToWorld(position, out result)); }
public Vec3D GlobalPosition(Vec3 enu_offset = default) { Vec3D result = position; RoiNode roi = node as RoiNode; // If we are a roi node based position we add roi position as local origin if (roi != null && roi.IsValid()) { result += roi.Position; } result += local_orientation * enu_offset; return(result); }
private void MapToRoi(MapPos result) { if (_topRoi == null) { return; } RoiNode roi = _topRoi.GetClosestRoiNode(result.position); result.node = roi; // Remove roiNode position as offset - Go to local RoiNode based coordinate system if (roi != null && roi.IsValid()) { result.position -= roi.Position; } }
public bool GetCartPos(MapPos pos, out CartPos result) { Coordinate converter = new Coordinate(); Vec3D position = pos.position; result = new CartPos(); // Check possibly local 3D under a roiNode RoiNode roi = pos.node as RoiNode; if (roi != null && roi.IsValid()) { position += roi.Position; } switch (_mapType) { case MapType.UNKNOWN: { return(false); } case MapType.UTM: UTMPos utmpos = new UTMPos(_utmZone, _north, -(position.z + _origin.z), position.x + _origin.x, position.y + _origin.y); converter.SetUTMPos(utmpos); break; case MapType.GEOCENTRIC: CartPos cartpos = new CartPos(position.x + _origin.x, position.y + _origin.y, position.z + _origin.z); converter.SetCartPos(cartpos); break; } return(converter.GetCartPos(out result)); }
static public void UnInitializeFactories() { Node.UnInitializeFactory(); Group.UnInitializeFactory(); Transform.UnInitializeFactory(); Lod.UnInitializeFactory(); State.UnInitializeFactory(); Geometry.UnInitializeFactory(); Scene.UnInitializeFactory(); PerspCamera.UnInitializeFactory(); DynamicLoader.UnInitializeFactory(); CullTraverseAction.UnInitializeFactory(); NodeAction.UnInitializeFactory(); Context.UnInitializeFactory(); Texture.UnInitializeFactory(); Roi.UnInitializeFactory(); RoiNode.UnInitializeFactory(); ExtRef.UnInitializeFactory(); }
static public void InitializeFactories() { Node.InitializeFactory(); Group.InitializeFactory(); Transform.InitializeFactory(); Lod.InitializeFactory(); State.InitializeFactory(); Geometry.InitializeFactory(); Scene.InitializeFactory(); PerspCamera.InitializeFactory(); DynamicLoader.InitializeFactory(); CullTraverseAction.InitializeFactory(); NodeAction.InitializeFactory(); Context.InitializeFactory(); Texture.InitializeFactory(); Roi.InitializeFactory(); RoiNode.InitializeFactory(); ExtRef.InitializeFactory(); Crossboard.InitializeFactory(); }
/// <summary> /// Converts a local mappos under a roi to a global position /// </summary> /// <param name="result"></param> /// <returns></returns> public bool ToGlobal(MapPos result) { if (result.node == null) // Already global { return(true); } // Remove roiNode position as offset - Go to local RoiNode based coordinate system RoiNode roi = result.node as RoiNode; if (roi != null && roi.IsValid()) { result.position += roi.Position; result.node = null; return(true); } return(false); // We failed to convert }
// Traverse function iterates the scene graph to build local branches on Unity GameObject Traverse(Node n, Material currentMaterial) { if (n == null || !n.IsValid()) { return(null); } string name = n.GetName(); if (String.IsNullOrEmpty(name)) { name = n.GetNativeTypeName(); } GameObject gameObject = new GameObject(name); var nodeHandle = gameObject.AddComponent <NodeHandle>(); nodeHandle.node = n; nodeHandle.inObjectDict = false; // ---------------------------- Check material state ---------------------------------- if (n.HasState()) { State state = n.State; if (state.HasTexture(0) && state.GetMode(StateMode.TEXTURE) == StateModeActivation.ON) { gzTexture texture = state.GetTexture(0); if (texture.HasImage()) { gzImage image = texture.GetImage(); int depth = (int)image.GetDepth(); int width = (int)image.GetWidth(); int height = (int)image.GetHeight(); if (depth == 1) { if (currentMaterial == null) { currentMaterial = new Material(Shader); } TextureFormat format = TextureFormat.ARGB32; ImageType image_type = image.GetImageType(); switch (image_type) { case ImageType.RGB_8_DXT1: format = TextureFormat.DXT1; break; } Texture2D tex = new Texture2D(width, height, format, false); byte[] image_data; image.GetImageArray(out image_data); tex.LoadRawTextureData(image_data); tex.filterMode = FilterMode.Trilinear; tex.Apply(); currentMaterial.mainTexture = tex; } image.Dispose(); } texture.Dispose(); } state.Dispose(); } // ---------------------------- Transform check ------------------------------------- gzTransform tr = n as gzTransform; if (tr != null) { Vec3 translation; if (tr.GetTranslation(out translation)) { Vector3 trans = new Vector3(translation.x, translation.y, translation.z); gameObject.transform.localPosition = trans; } } // ---------------------------- DynamicLoader check ------------------------------------- DynamicLoader dl = n as DynamicLoader; if (dl != null) { if (!nodeHandle.inObjectDict) { AddGameObjectReference(dl.GetNativeReference(), gameObject); nodeHandle.inObjectDict = true; } } // ---------------------------- Lod check ------------------------------------- Lod ld = n as Lod; if (ld != null) { foreach (Node child in ld) { GameObject go_child = Traverse(child, currentMaterial); NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!h.inObjectDict) { AddGameObjectReference(h.node.GetNativeReference(), go_child); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); h.inObjectDict = true; } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- Roi check ------------------------------------- Roi roi = n as Roi; if (roi != null) { nodeHandle.updateTransform = true; foreach (Node child in roi) { GameObject go_child = Traverse(child, currentMaterial); NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!h.inObjectDict) { AddGameObjectReference(h.node.GetNativeReference(), go_child); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); h.inObjectDict = true; } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- RoiNode check ------------------------------------- RoiNode roinode = n as RoiNode; if (roinode != null) { nodeHandle.updateTransform = true; } // ---------------------------- Group check ------------------------------------- Group g = n as Group; if (g != null) { foreach (Node child in g) { GameObject go_child = Traverse(child, currentMaterial); go_child.transform.SetParent(gameObject.transform, false); } return(gameObject); } // ---------------------------ExtRef check ----------------------------------------- ExtRef ext = n as ExtRef; if (ext != null) { AssetLoadInfo info = new AssetLoadInfo(gameObject, ext.ResourceURL, ext.ObjectID); pendingAssetLoads.Push(info); } // ---------------------------- Geometry check ------------------------------------- Geometry geom = n as Geometry; if (geom != null) { float[] float_data; int[] indices; if (geom.GetVertexData(out float_data, out indices)) { MeshFilter filter = gameObject.AddComponent <MeshFilter>(); MeshRenderer renderer = gameObject.AddComponent <MeshRenderer>(); Mesh mesh = new Mesh(); Vector3[] vertices = new Vector3[float_data.Length / 3]; int float_index = 0; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new Vector3(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2]); float_index += 3; } mesh.vertices = vertices; mesh.triangles = indices; if (geom.GetColorData(out float_data)) { if (float_data.Length / 4 == vertices.Length) { float_index = 0; Color[] cols = new Color[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { cols[i] = new Color(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2], float_data[float_index + 3]); float_index += 4; } mesh.colors = cols; } } if (geom.GetNormalData(out float_data)) { if (float_data.Length / 3 == vertices.Length) { float_index = 0; Vector3[] normals = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { normals[i] = new Vector3(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2]); float_index += 3; } mesh.normals = normals; } } //else // mesh.RecalculateNormals(); uint texture_units = geom.GetTextureUnits(); if (texture_units > 0) { if (geom.GetTexCoordData(out float_data, 0)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv = tex_coords; } } if ((texture_units > 1) && geom.GetTexCoordData(out float_data, 1)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv2 = tex_coords; } } if ((texture_units > 2) && geom.GetTexCoordData(out float_data, 2)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv3 = tex_coords; } } if ((texture_units > 3) && geom.GetTexCoordData(out float_data, 3)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv4 = tex_coords; } } } filter.sharedMesh = mesh; renderer.sharedMaterial = currentMaterial; } } return(gameObject); }
public bool UpdatePosition(MapPos result, GroundClampType groundClamp = GroundClampType.NONE, ClampFlags flags = ClampFlags.DEFAULT) { if (_currentMap == null) // No map { return(false); } if (groundClamp != GroundClampType.NONE) { // Add ROINode position as offset - Go to global 3D coordinate system as we need to clamp in global 3D RoiNode roi = result.node as RoiNode; if (roi != null && roi.IsValid()) { result.position += roi.Position; } Intersector isect = new Intersector(); Vec3D origo = new Vec3D(0, 0, 0); // Check camera frustrum ----------------------------------------------------------- if (_camera != null && _camera.IsValid()) { origo = _camera.Position; if ((flags & ClampFlags.FRUSTRUM_CULL) != 0) { isect.SetCamera(_camera); } } if ((flags & ClampFlags.ISECT_LOD_QUALITY) != 0) // Lets stand in the ray to get highest quality { origo = result.position; } Vec3 up = new Vec3(result.local_orientation.v13, result.local_orientation.v23, result.local_orientation.v33); // TODO: Fix this.... if (up.x == 0 && up.y == 0 && up.z == 0) { up.y = 1; } isect.SetStartPosition((Vec3)(result.position - origo) + 10000.0f * up); isect.SetDirection(-up); if (isect.Intersect(_currentMap, IntersectQuery.NEAREST_POINT | IntersectQuery.NORMAL | ((flags & ClampFlags.WAIT_FOR_DATA) != 0 ? IntersectQuery.WAIT_FOR_DYNAMIC_DATA : 0) | ((flags & ClampFlags.UPDATE_DATA) != 0 ? IntersectQuery.UPDATE_DYNAMIC_DATA : 0) , 1, true, origo)) { IntersectorResult res = isect.GetResult(); IntersectorData data = res.GetData(0); result.position = data.position + origo; result.normal = data.normal; result.clamped = true; } else { result.normal = up; result.clamped = false; } if (groundClamp == GroundClampType.GROUND) { result.normal = result.local_orientation.GetCol(2); } isect.Dispose(); // Drop handle and ignore GC // Remove ROINode position as offset - Go to local coordinate system under ROI Node if (roi != null && roi.IsValid()) { result.position -= roi.Position; } } return(true); }
//Add GameObjects to dictionary // Traverse function iterates the scene graph to build local branches on Unity GameObject Traverse(Node n, Material currentMaterial) { // We must be called in edit lock if (n == null || !n.IsValid()) { return(null); } // --------------------------- Add game object --------------------------------------- string name = n.GetName(); if (String.IsNullOrEmpty(name)) { name = n.GetNativeTypeName(); } GameObject gameObject = new GameObject(name); var nodeHandle = gameObject.AddComponent <NodeHandle>(); //nodeHandle.Renderer = Renderer; nodeHandle.node = n; nodeHandle.currentMaterial = currentMaterial; nodeHandle.ComputeShader = Settings.ComputeShader; // ---------------------------- Check material state ---------------------------------- if (n.HasState()) { State state = n.State; if (state.HasTexture(0) && state.GetMode(StateMode.TEXTURE) == StateModeActivation.ON) { gzTexture texture = state.GetTexture(0); if (!textureMaterialStorage.TryGetValue(texture.GetNativeReference(), out currentMaterial)) { if (texture.HasImage()) { ImageFormat image_format; ComponentType comp_type; uint components; uint depth; uint width; uint height; uint size; bool uncompress = false; Image image = texture.GetImage(); image_format = image.GetFormat(); image.Dispose(); switch (image_format) // Not yet { case ImageFormat.COMPRESSED_RGBA8_ETC2: if (!SystemInfo.SupportsTextureFormat(TextureFormat.ETC2_RGBA8)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGB8_ETC2: if (!SystemInfo.SupportsTextureFormat(TextureFormat.ETC2_RGB)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT1: case ImageFormat.COMPRESSED_RGB_S3TC_DXT1: if (!SystemInfo.SupportsTextureFormat(TextureFormat.DXT1)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT5: if (!SystemInfo.SupportsTextureFormat(TextureFormat.DXT5)) { uncompress = true; } break; } if (texture.GetMipMapImageArray(ref _image_texture_data, out size, out image_format, out comp_type, out components, out width, out height, out depth, true, uncompress)) { if (depth == 1) { if (n is Crossboard) { currentMaterial = new Material(Settings.CrossboardShader); } else { currentMaterial = new Material(Settings.DefaultShader); } TextureFormat format = TextureFormat.ARGB32; switch (comp_type) { case ComponentType.UNSIGNED_BYTE: { switch (image_format) { case ImageFormat.RGBA: format = TextureFormat.RGBA32; break; case ImageFormat.RGB: format = TextureFormat.RGB24; break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT1: case ImageFormat.COMPRESSED_RGB_S3TC_DXT1: format = TextureFormat.DXT1; break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT5: format = TextureFormat.DXT5; break; case ImageFormat.COMPRESSED_RGB8_ETC2: format = TextureFormat.ETC2_RGB; break; case ImageFormat.COMPRESSED_RGBA8_ETC2: format = TextureFormat.ETC2_RGBA8; break; default: // Issue your own error here because we can not use this texture yet return(null); } } break; default: // Issue your own error here because we can not use this texture yet return(null); } Texture2D tex = new Texture2D((int)width, (int)height, format, true); tex.LoadRawTextureData(_image_texture_data); switch (texture.MinFilter) { default: tex.filterMode = FilterMode.Point; break; case gzTexture.TextureMinFilter.LINEAR: case gzTexture.TextureMinFilter.LINEAR_MIPMAP_NEAREST: tex.filterMode = FilterMode.Bilinear; break; case gzTexture.TextureMinFilter.LINEAR_MIPMAP_LINEAR: tex.filterMode = FilterMode.Trilinear; break; } tex.Apply(texture.UseMipMaps, true); currentMaterial.mainTexture = tex; } } } // Add some kind of check for textures shared by many // Right now only for crossboards if (n is Crossboard) { textureMaterialStorage.Add(texture.GetNativeReference(), currentMaterial); } } nodeHandle.currentMaterial = currentMaterial; texture.Dispose(); } state.Dispose(); } // ---------------------------- Transform check ------------------------------------- gzTransform tr = n as gzTransform; if (tr != null) { Vec3 translation; if (tr.GetTranslation(out translation)) { Vector3 trans = new Vector3(translation.x, translation.y, translation.z); gameObject.transform.localPosition = trans; } // Notify subscribers of new Transform OnNewTransform?.Invoke(gameObject); } // ---------------------------- DynamicLoader check ------------------------------------- DynamicLoader dl = n as DynamicLoader; // Add dynamic loader as game object in dictionary // so other dynamic loaded data can parent them as child to loader if (dl != null) { List <GameObject> list; if (!NodeUtils.FindGameObjects(dl.GetNativeReference(), out list)) // We are not registered { NodeUtils.AddGameObjectReference(dl.GetNativeReference(), gameObject); nodeHandle.inNodeUtilsRegistry = true; // Added to registry // We shall continue to iterate as a group to see if we already have loaded children } else // We are already in list { return(list[0]); // Lets return first object wich is our main registered node } // Notify subscribers of new Loader OnNewLoader?.Invoke(gameObject); } // ---------------------------- Lod check ------------------------------------- Lod ld = n as Lod; if (ld != null) { foreach (Node child in ld) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!NodeUtils.HasGameObjects(h.node.GetNativeReference())) { NodeUtils.AddGameObjectReference(h.node.GetNativeReference(), go_child); h.inNodeUtilsRegistry = true; h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); } } go_child.transform.SetParent(gameObject.transform, false); } // Notify subscribers of new Lod OnNewLod?.Invoke(gameObject); // Dont process group as group is already processed return(gameObject); } // ---------------------------- Roi check ------------------------------------- Roi roi = n as Roi; if (roi != null) { nodeHandle.updateTransform = true; nodeHandle.inNodeUpdateList = true; updateNodeObjects.AddLast(gameObject); foreach (Node child in roi) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!NodeUtils.HasGameObjects(h.node.GetNativeReference())) { NodeUtils.AddGameObjectReference(h.node.GetNativeReference(), go_child); h.inNodeUtilsRegistry = true; h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- RoiNode check ------------------------------------- RoiNode roinode = n as RoiNode; if (roinode != null) { nodeHandle.updateTransform = true; nodeHandle.inNodeUpdateList = true; updateNodeObjects.AddLast(gameObject); } // ---------------------------- Group check ------------------------------------- Group g = n as Group; if (g != null) { foreach (Node child in g) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } go_child.transform.SetParent(gameObject.transform, false); } return(gameObject); } // ---------------------------ExtRef check ----------------------------------------- ExtRef ext = n as ExtRef; if (ext != null) { AssetLoadInfo info = new AssetLoadInfo(gameObject, ext.ResourceURL, ext.ObjectID); pendingAssetLoads.Push(info); } // ---------------------------- Crossboard check ----------------------------------- Crossboard cb = n as Crossboard; if (cb != null && GfxCaps.HasCapability(Capability.UseTreeCrossboards)) { // Scheduled for later build pendingBuilds.Enqueue(nodeHandle); } // ---------------------------- Geometry check ------------------------------------- Geometry geom = n as Geometry; if (geom != null) { nodeHandle.BuildGameObject(); // Notify subscribers of new Geometry OnNewGeometry?.Invoke(gameObject); // Later on we will identify types of geoemtry that will be scheduled later if they are extensive and not ground that covers other geometry // and build them in a later pass distributed over time // pendingBuilds.Enqueue(nodeHandle); } return(gameObject); }
public bool UpdatePosition(MapPos result, GroundClampType groundClamp = GroundClampType.NONE, ClampFlags flags = ClampFlags.DEFAULT) { if (_currentMap == null) // No map { return(false); } result.normal = result.local_orientation.GetCol(2); if (groundClamp != GroundClampType.NONE) { // Add ROINode position as offset - Go to global 3D coordinate system as we need to clamp in global 3D RoiNode roi = result.node as RoiNode; if (roi != null && roi.IsValid()) { result.position += roi.Position; } // The defined down vector Vec3 down = new Vec3(-result.local_orientation.v13, -result.local_orientation.v23, -result.local_orientation.v33); // Check triangel ground if (result.clampResult.HasFlag(IntersectQuery.ABC_TRI)) { if (Intersect(result.position, down, result.a, result.b, result.c, out Vec3D p)) { result.position = p; ToLocal(result); return(true); } } // Check new intersector Intersector isect = new Intersector(); Vec3D origo = new Vec3D(0, 0, 0); // Check camera frustrum ----------------------------------------------------------- if (_camera != null && _camera.IsValid()) { origo = _camera.Position; if ((flags & ClampFlags.FRUSTRUM_CULL) != 0) { isect.SetCamera(_camera); } } if ((flags & ClampFlags.ISECT_LOD_QUALITY) != 0) // Lets stand in the ray to get highest quality { origo = result.position; } isect.SetStartPosition((Vec3)(result.position - origo) - 10000.0f * down); // Move backwards isect.SetDirection(down); if (isect.Intersect(_currentMap, IntersectQuery.NEAREST_POINT | IntersectQuery.ABC_TRI | (flags.HasFlag(ClampFlags.ALIGN_NORMAL_TO_SURFACE) ? IntersectQuery.NORMAL : 0) | //IntersectQuery.NORMAL | (flags.HasFlag(ClampFlags.WAIT_FOR_DATA) ? IntersectQuery.WAIT_FOR_DYNAMIC_DATA : 0) | (flags.HasFlag(ClampFlags.UPDATE_DATA) ? IntersectQuery.UPDATE_DYNAMIC_DATA : 0) , 1, true, origo)) { IntersectorResult res = isect.GetResult(); IntersectorData data = res.GetData(0); result.position = data.coordinate + origo; if ((data.resultMask & IntersectQuery.NORMAL) != 0) { result.normal = data.normal; } if (data.resultMask.HasFlag(IntersectQuery.ABC_TRI)) { result.a = data.a + origo; result.b = data.b + origo; result.c = data.c + origo; } result.clampResult = data.resultMask; } else { result.clampResult = IntersectQuery.NULL; } //if (groundClamp == GroundClampType.GROUND) //{ // result.normal = result.local_orientation.GetCol(2); //} isect.Dispose(); // Drop handle and ignore GC // Remove ROINode position as offset - Go to local coordinate system under ROI Node ToLocal(result); } result.clampFlags = flags; result.clampType = groundClamp; return(true); }