Below are some videos of what i have at the moment for the ROV moving through the underwater detector. Everything is craft models. For the cone i am using two superimposed PseudoMesh Cones with normal and inverted normals with the fading texture plus a craft spot light. The view point can be far away or can be centred on the ROV. I am pretty happy with the results. Thanks for all your help.

@dave1707 here is a stripped down version of the lighting section. Uses @LoopSpace 's PseudoMesh models.

-- Test spotlight lighting with cone
-- PiInTheSky, 8/12/19
-- requires LoopSpace's PseudoMesh Models
function setup()
parameter.number("e1",0,360,90)
parameter.number("e2",0,360,0)
parameter.number("e3",0,360,0)
parameter.number("x",-1000,1000,0)
parameter.number("y",-1000,1000,0)
parameter.number("z",-1000,1000,0)
parameter.number("coneAngle",0,90,30)
parameter.integer("ambientIntensity",0,255,60)
parameter.number("sunIntensity",0,1,0.0)
parameter.integer("lightIntensity",0,10,5)
parameter.number("lightDecay",0,10,5)
-- Create a new craft scene
scene = craft.scene()
v=scene.camera:add(OrbitViewer,vec3(0,0,0), 1000, 0, 2000)
v.camera.farPlane=3000
scene.ambientColor=color(ambientIntensity,ambientIntensity,ambientIntensity,255)
sunLight=scene.sun:get(craft.light)
-- create cube of spheres
for x=-5,5 do
for y=-5,5 do
for z=-5,5 do
createSphere(vec3(x*60,y*60,z*60))
end
end
end
--texture for cone transparency
coneTexture=image(255,255)
setContext(coneTexture)
for i=1,255 do
for j=1,255 do
mycol=color(38, 104, 243, j*0.5)
coneTexture:set(i,j,mycol )
end
end
setContext()
--set up PseudoMesh cones with normals normal and inverted
local coneMesh = PseudoMesh()
coneMesh:addCylinder({
ends=0,
axis=vec3(0,1,0),
height=1,
startRadius=1,
endRadius=0.001,
centre=vec3(0,-0.5,0),
size=30, --number of facets
})
coneModel= coneMesh:toModel()
cone1=scene:entity()
cone1.model =coneModel
cone1.material = craft.material("Materials:Basic")
cone1.position=vec3(0,10,0)
cone1.material.map=coneTexture
cone1.material.blendMode=NORMAL
coneMesh:invertNormals()
coneModel2= coneMesh:toModel()
cone2=scene:entity()
cone2.parent=cone1 --inherents coord transforms of cone1
cone2.model =coneModel2
cone2.material = craft.material("Materials:Basic")
cone2.material.map=coneTexture
cone2.material.blendMode=NORMAL
--add spot light
conespot=cone1:add(craft.light,SPOT)
conespot.distance=500
conespot.penumbra=1
conespot.intensity=lightIntensity
conespot.decay=lightDecay
end
function createSphere(p)
local s=scene:entity()
s.position=vec3(p.x,p.y,p.z)
s.model = craft.model.icosphere(5,3)
s.material = craft.material("Materials:Specular")
s.material.diffuse=color(255,0,0)
end
function update(dt)
cone1.position=vec3(x,y,z)
cone1.eulerAngles=vec3(e1,e2,e3)
conespot.intensity=lightIntensity
conespot.decay=lightDecay
conespot.angle=coneAngle
local xzscale=math.tan(math.rad(coneAngle))
cone1.scale=vec3(xzscale,1,xzscale)*500*math.pow(lightIntensity,0.3)/lightDecay
scene.ambientColor=color(ambientIntensity,ambientIntensity,ambientIntensity,255)
sunLight.intensity=sunIntensity
scene:update(dt)
end
function draw()
update(DeltaTime)
scene:draw()
end

@piinthesky Thanks for the above code, but I gave up trying to get it to run. Trying to include Loopspaces code, getting errors because it might not be the right code, trying to find the right code, still getting errors. I didn’t think it was going to be that involved or I’m just not finding the correct code to include. I found the code for his models which I assume you’re referring to. I ran that and it showed several different colored shapes rotating. I tried to pull what I thought I needed out of that, but apparently that wasn’t right. Is there just the code of his that I need to include or do I have to pull it out of one of his examples someplace.

@dave1707 you would need to include the PseudoMesh class which @LoopSpace provides in the first entry of this discussion thread. Then you need also his MeshExt library which he also indicates where to find in a later entry in the thread. i have found them very useful libraries, so it is well worth the effort to get them into your collection of code.

@piinthesky Got everything loaded. The code you show above now works. The only problem is the amount of code to look thru to understand how your code works.

@Bri_G Try using this PseudoMesh class instead of the one at the beginning of the discussion. Let me know if this works.

PseudoMesh = class()
function PseudoMesh:init()
self.vertices = {}
self.texCoords = {}
self.normals = {}
self.colors = {}
self.size = 0
end
function PseudoMesh:vertex(k,v)
if v then
self.vertices[k] = v
else
return self.vertices[k]
end
end
function PseudoMesh:normal(k,v)
if v then
self.normals[k] = v
else
return self.normals[k]
end
end
function PseudoMesh:texCoord(k,v)
if v then
self.texCoords[k] = v
else
return self.texCoords[k]
end
end
function PseudoMesh:color(k,v)
if v then
self.colors[k] = v
else
return self.colors[k]
end
end
function PseudoMesh:setColors(c)
for k=1,self.size do
self.colors[k] = c
end
end
function PseudoMesh:resize(k)
self.size = k
end
local mm = getmetatable(mesh())
function PseudoMesh:addJewel(t)
return mm.addJewel(self,t)
end
function PseudoMesh:addPyramid(t)
return mm.addPyramid(self,t)
end
function PseudoMesh:addPolygon(t)
return mm.addPolygon(self,t)
end
function PseudoMesh:addCone(t)
return mm.addCone(self,t)
end
function PseudoMesh:addBlock(t)
return mm.addBlock(self,t)
end
function PseudoMesh:addCylinder(t)
return mm.addCylinder(self,t)
end
function PseudoMesh:addSphere(t)
return mm.addSphere(self,t)
end
function PseudoMesh:addSphereSegment(t)
return mm.addSphereSegment(self,t)
end
function PseudoMesh:invertNormals()
for k,v in ipairs(self.normals) do
self.normals[k] = -v
end
end
function PseudoMesh:toModel()
local m = craft.model()
local i = {}
local n = #self.vertices
for k=1,n,3 do
if (self.vertices[k+1] - self.vertices[k]):cross(self.vertices[k+2] - self.vertices[k]):dot(self.normals[k+1] + self.normals[k+2] + self.normals[k]) < 0 then
table.insert(i,k)
table.insert(i,k+1)
table.insert(i,k+2)
else
table.insert(i,k)
table.insert(i,k+2)
table.insert(i,k+1)
end
end
m.positions = self.vertices
m.normals = self.normals
m.uvs = self.texCoords
m.colors = self.colors
m.indices = i
return m
end
function extendModel()
local mt = getmetatable(craft.model)
if mt.__extended then
return true
end
local mm = getmetatable(mesh())
if not mm.__extended then
return false
end
rawset(mt,"jewel", function(t)
local m = PseudoMesh()
mm.addJewel(m,t)
return m:toModel()
end)
rawset(mt,"pyramid", function(t)
local m = PseudoMesh()
mm.addPyramid(m,t)
return m:toModel()
end)
rawset(mt,"polygon", function(t)
local m = PseudoMesh()
mm.addPolygon(m,t)
return m:toModel()
end)
rawset(mt,"block", function(t)
local m = PseudoMesh()
mm.addBlock(m,t)
return m:toModel()
end)
rawset(mt,"cylinder", function(t)
local m = PseudoMesh()
mm.addCylinder(m,t)
return m:toModel()
end)
rawset(mt,"sphere", function(t)
local m = PseudoMesh()
mm.addSphere(m,t)
return m:toModel()
end)
rawset(mt,"sphereSegment", function(t)
local m = PseudoMesh()
mm.addSphereSegment(m,t)
return m:toModel()
end)
rawset(mt.___class,"append", function(s,m,o)
o = o or vec3(0,0,0)
local nv = s.vertexCount
local ni = s.indexCount
local n = m.size
s:resizeVertices(nv+n)
s:resizeIndices(ni+n)
local i = {}
for k=1,n,3 do
if (m.vertices[k+1] - m.vertices[k]):cross(m.vertices[k+2] - m.vertices[k]):dot(m.normals[k+1] + m.normals[k+2] + m.normals[k]) < 0 then
table.insert(i,k)
table.insert(i,k+1)
table.insert(i,k+2)
else
table.insert(i,k)
table.insert(i,k+2)
table.insert(i,k+1)
end
end
for k=1,n do
s:position(nv+k,m.vertices[k]+o)
s:normal(nv+k,m.normals[k])
s:color(nv+k,m.colors[k])
s:uv(nv+k,m.texCoords[k])
s:addElement(i[k])
end
end)
rawset(mt,"__extended",true)
return true
end
local exports = {
extendModel = extendModel
}

@dave1707 glad it works now. The @LoopSpace code is very complete, but dont ask me to explain it! By the way his sphere wraps a texture correctly, unlike the native codea sphere.

@Bri_G There a lot of code there, over 2000 lines. Maybe once you understand a small section of it, the rest is just a repeat for the different objects.

Latest versions of my code can be found on github. I use them a fair bit so I do try to fix bugs as I encounter them, and add new stuff when I think it's useful. I've added that link to the opening post so it's easier to find.

## Comments

Below are some videos of what i have at the moment for the ROV moving through the underwater detector. Everything is craft models. For the cone i am using two superimposed PseudoMesh Cones with normal and inverted normals with the fading texture plus a craft spot light. The view point can be far away or can be centred on the ROV. I am pretty happy with the results. Thanks for all your help.

@piinthesky - wow, sorry about suggestions, judging by the new videos you were obviously well beyond where I thought you were. Very impressive!!!

@piinthesky Those are great. Is there any chance you can strip out the code and show a simple example of just the lighting.

@dave1707 here is a stripped down version of the lighting section. Uses @LoopSpace 's PseudoMesh models.

@piinthesky Thanks for the above code, but I gave up trying to get it to run. Trying to include Loopspaces code, getting errors because it might not be the right code, trying to find the right code, still getting errors. I didn’t think it was going to be that involved or I’m just not finding the correct code to include. I found the code for his models which I assume you’re referring to. I ran that and it showed several different colored shapes rotating. I tried to pull what I thought I needed out of that, but apparently that wasn’t right. Is there just the code of his that I need to include or do I have to pull it out of one of his examples someplace.

@piinthesky Thanks. I’ll try to located them and try again.

@piinthesky Got everything loaded. The code you show above now works. The only problem is the amount of code to look thru to understand how your code works.

@dave1707 - I’ve loaded the above code, PseudoMesh and MeshExt library with dependencies but still not working - fails on coneMesh:addCylinder().

@Bri_G I was getting that when I first started, that’s where I gave up. I’ll have to look at what I included and where I got it from.

@Bri_G Try using this PseudoMesh class instead of the one at the beginning of the discussion. Let me know if this works.

@dave1707 - with dependencies that works - now to try and understand code. Thanks.

@Bri_G There a lot of code there, over 2000 lines. Maybe once you understand a small section of it, the rest is just a repeat for the different objects.

Latest versions of my code can be found on github. I use them a fair bit so I do try to fix bugs as I encounter them, and add new stuff when I think it's useful. I've added that link to the opening post so it's easier to find.

Happy to answer questions about it!

@LoopSpace - thanks for the update, I lose track of where all the valuable resources are.