Wednesday, March 17. 2010
I removed some of yesterdays code and did it in a slightly different way. The reason is, that I had a, I think, good idea. Yesterday I stored the assignment of storage to the pins directly in the pins, but that means, I can have only one mapping (or it gets very ugly). But when thinking about how to continue I found out, that I will soon want to have the ability to see, what an arbitrary channel will create. And for that I need to be able to evaluate the operators. For example I would like to have an operator which mixes two images using a third one, so that the first image is superimposed with the second whenever the control images intensity is over for example 0.9. But that will be much easier if I can actually see the images. So I would want the UI of the operator doing the mixing to be able to display the three input images and the output image. That way I can visually change some settings. In general I will probably not put the images into the operator UI, but into some other place so that changing operators doesn't close them. E.g. if the control image is done by some procedural noise function I would probably like to see, what happens to the output if I change the settings of the noise.
As I wrote yesterday, I started with the gathering of the list of objects. The objects have to match some criterion (it is done with a simple function which receives the object and then returns true if the object can be used) and now there is a function which gathers all objects in the scene and records their path. Up to now I only had a function which returned the object which were directly contained by some object, so it could not look into groups. The code is untested, but on Friday I hope to start using it. As soon as it is working I will try to get the rest of the new class into a working state, the visual selection thing is secondary. I rarely used that in the past, so I guess not much harm is done to postpone it. But getting the old code removed and the new one taking over is an important step.
Tuesday, March 16. 2010
I have also made some progress on the Channel Material. The preprocessing function is working now and each used pin should now know where to find data or where to put it. So next is actually evaluating the operators to create a texture of the Channel Material I can use in OpenGL. I can't really represent the shader models (e.g. Ward BRDF) and only get a very coarse idea what the material will look like, but I guess that is ok for now. What would actually be possible is, to create a real OpenGL shader program to load directly into the GPU. But that will be something to be done at a different time, I guess.
The function to find the complete path of the first object is working. I haven't tested it thoroughly, I only put a box in a group, but that worked well and is all I need for now. Now the second part, selecting another object. I have been thinking about some ways. The current code lists all objects of the right type which are directly contained in the model. It would be great, if I could also add the objects in the groups and identify them. I am not sure if I should do so, it would be possible, but still the list might get prohibitively long in complex scenes. But perhaps it is best to implement it and worry later about that problem. There are always ways to structure the list, once I see, how I really use the program when I have huge models consisting of many objects. So I guess I will add them and as name use a concatenation of all names of the path leading to the object. I have also had an idea how to select the object visually. Currently I can only select an object, then look into it and in case of a group select one of the contained objects. But that is only a limitation in the API, the hit stack created by OpenGL should actually make it possible to directly get the path. I guess I will have to implement that operation, it is way too useful and I guess I will use it in some parts of the program. If not now, then in the future.
Monday, March 15. 2010
I continued with the object which will store the necessary data to calculate the transformation matrix from one objects coordinates into another ones. The code to load and store the data is completed for now, I will have to extend it, as I have to connect callbacks to the loaded object, something I haven't done yet. I have also started to implement the function to create the UI (it isn't doing much at the moment) and I have added the object to the CSG-modifier. Then I started to implement a function to find out the first half of the mapping, the sequence of ObjectPointers to the object which includes the object. I think, I can get that information from the selection, as my selection objects always contain a pointer to the parent selection. The parent selection is the selection which was active before and that contains pointers to the object which was selected before the current object was. So I hope I can reconstruct the path through the object hierarchy with that information. That is the easy part, then I have to implement the selection of the second object. I am still considering different options for an UI. And I will probably add an editor to select the object by clicking it. But there too I am not sure yet, how to implement it. But at least the first steps are clear, I will add all the necessary code to add the features I currently have so I can start to remove the old code and switch over as soon as possible.
Sunday, March 14. 2010
I also worked briefly on the Channel Material. The first part of the preprocessing is done, I have a list of operators to evaluate and the list of default values I will need. Very important in this is, that the list of operators is ordered so that the evaluation of an operator depends only on the default values and the values calculated by operators before it. So now I will run through that list and "allocate" memory for the operators and tell the operators where they find their input values. The memory is not really allocated, that will be done when evaluating the structure, I only need to calculate the size of memory needed and give the memory map to the operators.
I guess the title is scary, but it is actually quite easy what I started today. To finally get the socket into the wall, I need the ability to cut out a hole. As I still haven't fixed the problem in the CSG, that it needs at least one edge of an object to run through a closed loop of the other, I implemented the huge change to the edge loop modifier, which I finished yesterday. So what is keeping me from adding the socket is, that the box I need for cutting the hole is part of the group which combines the elements of the socket. And I can't access that object from the CSG-difference. The problem is, that the current code can only access two object pointers, one I need for the wall, the other would be the box. But as it is in a group, I wouldn't get the full transformation. The problem stems from the ability of my program to recreate the geometry, therefore I need access to the object after I have defined the CSG-operation. Worse, I want it to react to any changes in position and so it has to have the ability to get the complete transformation. For the user that means I want to be able to move the socket and the hole is supposed to move together with it. To finally fix this problem, I started with a new object which will store pointers to all the relevant objects so I can recalculate the transformation. As that is basically the topological information it should explain the strange title. Currently not much is working, the object exists and it has some storage for information. But only storing is implemented, I still have to add loading tomorrow. It is quite hard to tell, how long I will need for this thing, but I hope it will be easier than the last thing.
Saturday, March 13. 2010
Today I implemented the rest of the code to finish the still open problems. The edge loop now has a nice little label to show the direction of the edge being split. That way numerical control is possible and I already played a little bit with it and it works quite well. The biggest problem was to add some form of minimum size for the label. The code I had written was completely ok, but it didn't work. At the time I thought I had done something wrong and tried some other things, but in the end I found out, that the multiplication of a vector with a matrix was wrong. It didn't use the values of the fourth row. Normally not a problem as the usual affine transformations have a last row consisting of 0, 0, 0, 1 and that can be ignored. But as I had to transform a vector by the projection transformation it resulted in wrong results, as that matrix has a very different last row (it is not an affine transformation). So in the end I found a very, very old bug and made the program a bit slower, but at least now it works.
Friday, March 12. 2010
I have continued a bit on the edge loops. It is always quite some work to get something into the OpenGL-renderer, as I have to be careful to not bind the modeler core to OpenGL. I hope to finish this thing tomorrow and then continue with the room to finally create some renderings for the socket and the light switch. It might sound excessive to go to such lengths to get some renderings for two small objects, but I had problems to do those renderings quite often in the past. So I want to finally fix these problems so that I can create the necessary models more easily in the future. The features will be useful in future models, I am very sure of that.
Wednesday, March 10. 2010
I am back at where I was before I started to implement the shader operator. I guess for now I will try to implement what I have currently and then see, how to fix the rest of the problems. So as the default model of the Channel Material is now nearly a working version (I didn't define the shader to use, I basically have an empty container), I hope to finished the preprocessing step and then implement a simple OpenGL-version of the material. It will just create a texture and then use a Phong shader.
Tuesday, March 9. 2010
Edge LoopI added a new UI-control to show the length of the edge being split. So now only the second part is missing, adding a transparent quad with a texture with a "+" and a "-" on it to show in which direction the edge will move. Channel MaterialI have defined all the necessary pins for the shader model. When doing so I also thought about the next steps and there are some problems. One is, that the raytracer uses quite different data and for example handles antialiasing whereas the OpenGL-renderer doesn't. I will have to think about a way to handle that, I only have an idea at the moment. If possible I would like to avoid to implement the operators twice, once for OpenGL and once for the raytracer.
Monday, March 8. 2010
Continuing with the channel material is not as easy as I had thought. The problem to finished the preprocessing step is, that the output operator had the wrong pin-type. For some reasons the shaders need to output quite some data so I can use it in the raytracer. So I had to add a new pin type to represent that. And now I first need to implement a component turning color into shader output. I could obviously just leave it at the color pin I use now, but honestly I would not like to write much code I will very soon have to throw away. So I decided, that I will add an adapter to the list of operators which will use the shader models I have for my other material class and make it usable for the Channel Shaders. I always intended to add that so I can at least use some of the code I have written for my older, simpler system.
When I tried to use the result of the Edge Loop-modifier I found out, that something didn't work correctly. I obviously didn't get the correct length of the edge. When I today looked into it I found out, that the Change Geometry had a bug, when an edge was split multiple times it didn't correctly record that in a map. So I fixed that, although I already knew at that point, that it won't be the correct solution. But it is a very important class and so fixing problems with it is also very important. In the meantime I have found an easy way to get the length of an edge. I could destroy it if I made a change in the future, so tomorrow I will add a comment to explain that. But I am still not finished, there is one more problem. I can't see, where the edge starts, so if I want to split an edge close to the middle, I can't tell if I use the right length. I think I will add a small helper tomorrow which shows a texture with "+" and "-" so I can immediately tell, which direction is which.
Saturday, March 6. 2010
I have finished the changes to the Edge Loop modifier. It now works mostly as I expect it. There is a small issue where values only change after the scene is refreshed I don't quite understand, but it doesn't look too bad to use. So tomorrow I will finally try to use it for a real model.
Friday, March 5. 2010
I was so lazy yesterday, I haven't done anything at all. Today I have continued with adding the Channel Material to the OpenGL-part of the program. The first step to use the Channel Material is to evaluate the graph of operators and build some structures. As I know, that the graph has no loops as I simply don't allow them (the program currently doesn't make any checks if there are any, though), I can evaluate the operators in a sequence, so that the input values of any operator are available when I evaluate it. That means the first structure I need is a list of operators. This list defines in what sequence the operators are evaluated. As it only contains operators reachable from the output operator, it also means that I can add as many dummy operators as I like to the material, evaluation will not suffer. I think that is an important aspect as it allows to play with alternatives. The second structure is the size of the necessary state. The state is the sum over all output values and the input values to the channel shader. The input values are things like the uv-coordinates, the 3D position and the normal of the point where we want to evaluate the shader. What the evaluation step has to do besides creating the list of operators is to tell each operator where it shall store its output and where it can find its input. All inputs which are not connected will receive a default position to read, so a pin for 2d-coordinates will receive the original texture coordinates. For channel types where there is no input, e.g. the color, I will create dummy places filled with some default value, e.g. black for the color or 0 for the intensity.
|