Here is my code
struct Ray {
vec3 origin;
vec3 direction;
bool hit;
Sphere object;
float t;
};
struct Sphere {
vec3 origin;
float radius;
BasicMaterial material;
};
Now, when I create a Ray,my goal is that the object be NULL.
Ray r;
r. origin = origin;
r.direction = dir;
r.hit = false;
r.object = NULL;
r.t = FLT_MAX;
When I run it, I get
error C1503: undefined variable "NULL"
One way I could think of is make a dummy object and initialise with that every time. Is there any better way to do it?
Something like NULL doesn't exist in GLSL. See the most recent OpenGL Shading Language 4.60 Specification (HTML).
Sphere object is not an object reference. The type of object is the structure Sphere. When you assign a variable (s) of type Sphere to object
Sphere s;
Ray r;
r.object = s;
all the elements of s are copied to r.object. GLSL has no concept of objects, object references, inheritance or polymorphism.
Hence the element Sphere object in the structure Ray doesn't make sense. In GLSL you would need to write a function that calculates the intersection of a Ray and a Sphere:
struct Ray
{
vec3 origin;
vec3 direction;
};
struct Sphere
{
vec3 origin;
float radius;
BasicMaterial material;
};
bool IntersectRaySphere(in Ray r, in Sphere s, out float t)
{
// [...]
}
Related
Title may be a little bit confusing but basically I have a class 'Quaternion' which has 2 parameters, the first being another instance of a class Vector3 and the other being a float.
Vector3 takes 3 floats as parameters and assigns them to x, y, and z.
I want to set default parameters for the Quaternion class but I am unsure how to set default parameters with a class as a parameter.
Vector3
class Vector3 {
public:
float x, y, z;
Vector3(float uX, float uY, float uZ) {
this->x = uX;
this->y = uY;
this->z = uZ;
}
};
Quaternion
class Quaternion {
public:
Vector3 axis;
float scalar;
Quaternion(Vector3 uAxis, float uScalar = 0) {
axis = uAxis;
scalar = uScalar;
};
};
I would like to have the default parameter for uAxis to be a Vector3 with x, y, and z set to 1, 0, 0 respectively, but i am unsure how i can do this.
I think this is what you were looking for:
class Quaternion {
public:
Vector3 axis;
float scalar;
Quaternion(Vector3 uAxis = Vector3(1.0, 0.0, 0.0), float uScalar = 0) {
axis = uAxis;
scalar = uScalar;
};
};
It is possible to call a constructor of a class to set a default parameter. Here is the corresponding cpp reference default arguments.
This is what you want. Always use the initialisation list on the constructor unless you have to do something with the parameters docs. Also I am passing the uAxis as const reference which is always a good thing to do for ADT (Abstract Data Types) Unless you have special requirements.
class Quaternion
{
Vector3 axis;
float scalar;
public:
Quaternion(const Vector3 & uAxis = Vector3(1.0, 0.0, 0.0), float uScalar = 0) :
axis(uAxis),
scalar(uScalar)
{
}
};
Another option would be to use default member initialization for axis within Quaternion. That way, just creating a Quaternion q{} would set axis to whatever you want. [Demo]
class Quaternion {
public:
Vector3 axis{1.0, 0.0, 0.0};
float scalar{};
Quaternion() = default;
...
};
For the Quaternion(Vector3 uAxis, float uScalar) constructor, it would be preferable to use a member initializer list:
Quaternion(Vector3 uAxis, float uScalar) : axis{uAxis}, scalar{uScalar} {};
Also, you can remove Vector3's constructor, making Vector3 an aggregate:
struct Vector3 {
float x{};
float y{};
float z{};
};
Vector3 v{1.1, 2.2, 3.3};
so i am trying to build a game and i have the following code:
// Vector2 is just a struct that represents a vector is 2D space.
// predefining these structs
struct SILO;
struct ICBM;
struct MISSILE;
struct ICBM{
Vector2 launch;
Vector2 target;
Vector2 pos;
int Velocity;
ICBM(){
// Implementation not shown
}
void move(){
// implementation not shown
}
};
struct MISSILE{
Vector2 launch;
Vector2 target;
Vector2 pos;
int Velocity;
MISSILE(Vector2 t, SILO origin){
launch = (Vector2) {origin.Object.x, origin.Object.y};
target = t;
pos = launch;
Velocity = 10;
}
void move(){
// implementation not shown
}
};
struct SILO{
Rectangle Object; // Rectangle has attributes x and y
Vector2 pos;
};
I predefined all of the structs in the beginning so they can reference eachother. However, the constructor of the struct MISSILE will result in an error saying that SILO is an incomplete type.
I could change the constructor parameter into MISSILE(Vector2 t, SILO* origin). However, when i try to access the attributes, it will result in the same error.
Is there any way I can solve this problem WITHOUT changing the position of where SILO is defined?
You could use a SILO* in your MISSILE constructor, instead a copy of the whole object?!
MISSILE(Vector2 t, SILO* origin){
launch = (Vector2) {origin->Object.x, origin->Object.y};
I'm having a ModelMatrix class in which i have a glm::vec3 defined as
glm::vec3 *position = nullptr;
Then i got a setter method
void ModelMatrix::SetPosition(const glm::vec3 &position)
{
delete this->position;
*this->position = position;
}
at asigning the constant reference the problem occurs.
It goes inside this method
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec3<T, P>& tvec3<T, P>::operator= (tvec3<T, P> const & v)
{
this->x = v.x;
this->y = v.y;
this->z = v.z;
return *this;
}
And then just crashes on the first line of the method.
This is a snippet from the call stack.
glm::detail::tvec3<float, (glm::precision)0>::operator= at type_vec3.inl:189 0x404f78
core3d::ModelMatrix::SetPosition() at ModelMatrix.cpp:58 0x405bc3
core3d::ModelMatrix::ModelMatrix() at ModelMatrix.cpp:7 0x40582b
I don't have any error message.
What is causing this error?
The much better approach here is to not use a pointer at all. glm::vec3 is a fixed size type that probably uses 12 or 16 bytes. I see absolutely no need to use a separate dynamic allocation for it.
So where you currently declare your class member as:
glm::vec3 *position;
simply change this to:
glm::vec3 position;
Then remove all the new/delete calls you currently have for the class member. The setter method then becomes:
void ModelMatrix::SetPosition(const glm::vec3 &position)
{
this->position = position;
}
This is because you are deferencing memory which you've now deallocated:
delete this->position;
*this->position = position;
I don't know why you are bothering to delete it, as I don't think the glm::vec3 destructor actually does anything important, so you can just do:
*this->position = position;
I am trying to implement software renderer, which interpolation happens after vertex shading
The following is its declaration
template <class T>
class Interpolatable
{
// The function calculates an interpolated value
// along the fraction t between 0.0 and 1.0.
// When t = 1.0, endValue is returned.
virtual T interpolate(const T &endValue, float t)=0;
};
struct Vertex: public Interpolatable<?????????>
{
float x, y, z;
Vertex()=default;
Vertex(float, float, float);
virtual Vertex &interpolate(const Vertex &endValue, float t) const;
};
Is it possible to make Vertex's interpolate method return instance of Vertex?
The compiler keeps giving me errors
You can pass a class' name as a template argument safely, but any errors you're getting are due to a function signature mismatch.
struct Vertex: public Interpolatable<Vertex>
virtual T interpolate(const T &endValue, float t)=0;
virtual Vertex &interpolate(const Vertex &endValue, float t) const;
// ^reference ^declared const
It seems that your signatures should be:
virtual T interpolate(const T &endValue, float t) const =0;
virtual Vertex interpolate(const Vertex &endValue, float t) const;
It should work if you fix the three errors:
????????? should be Vertex
interpolate should return Vertex by value
interpolate should not be const (or should be const in the base class)
I have this class:
class Texture
{
public:
//I need this variable in this format
float diffuseColor[3];
}
But I'd like to make an easier interface than dealing with "diffuseColor[0]" and such, something like:
myTexture.color.r = 1.0f; //this is diffuseColor[0]
So I'm trying to get a class that works as a shell to the diffuseColor values, something like:
class Color
{
public:
float *r, *g, *b;
}
And in my Texture class:
class Texture
{
public:
Texture()
{
color.r = &diffuseColor[0];
color.g = &diffuseColor[1];
color.b = &diffuseColor[2];
}
Color color;
private:
float diffuseColor[3];
}
But the way it is now, I have to de-reference the color values if I want to use them:
(*myTexture.color.r) = 1.0f;
How can I achieve this without having to de-reference it everytime I want to use it?
You can use references which would be initialized in the member initializer list:
struct Color {
Color(float* colors): r(colors[0]), g(colors[1]), b(colors[2]) {}
float& r;
float& g;
float& b;
};
class Texture {
float diffuseColor[3];
public:
Color color;
Texture(): diffuseColor(), color(this->diffuseColor) {}
};
If you need to copy and/or assign Texture objects, you'll also need to implement a copy constructor and an assignment operator. Also note that this convenience has a relatively steep costs: both the pointers and the reference approach will increase the size of the Texture objects by 3 pointer. You might be better off to use accessors, instead, e.g.:
class Texture {
float diffuseColor[3];
public:
float& r() { return this->diffuseColor[0]; }
float& g() { return this->diffuseColor[1]; }
float& b() { return this->diffuseColor[2]; }
};
Maybe you can use the union language feature of C++:
union ColorUnion {
// first representation (Texture)
struct TextureColor {
float diffuseColor[3];
}
// second representation (RGB)
struct RGBColor {
float r;
float g;
float b;
}
};